Rounding to the nearest range with modulo

Tagged modulo, range  Languages ruby
require 'pp'
hash = Hash.new {|h,k| h[k] = [] }
(0..99).step(5).each do |num|
  # XXX: 10 - 10%10 => 10
  range = num - num%10
  hash[range] << num
end
pp hash

{0=>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 10=>[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 20=>[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 30=>[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 40=>[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 50=>[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 60=>[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 70=>[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
 80=>[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
 90=>[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]}

Fetch the status of Postgres' streaming replication with ActiveRecord and Rails

Tagged pg_current_wal_flush_lsn, pg_last_wal_receive_lsn, postgres, replication, streaming  Languages ruby

When using streaming replication you can use this code to fetch the number of bytes the slave is behind the master in applying changes to the WAL (write-ahead log):

class SlaveDatabase < ApplicationRecord
  self.abstract_class = true
  # NOTE: Add slave entry to config/database.yml
  establish_connection :slave

  #
  # Returns the number of bytes the slave is behind the master in applying WAL updates.
  #
  def self.replication_delta
    # Returns, for example, 12/547C3A58 from the master
    current_master_wal = ActiveRecord::Base.connection.select_value("SELECT pg_current_wal_flush_lsn();")
    # Returns, for example, -7504582 from the slave
    delta = connection.select_value("SELECT #{connection.quote(current_master_wal)} - pg_last_wal_receive_lsn()")
    raise "pg_last_wal_receive_lsn returned null, see documentation for details" unless delta
    Integer(delta).abs
  end
end

Tested with version Postgres 10. Note that in version 10, pg_last_xlog_receive_location has been renamed to pg_last_wal_receive_lsn, and pg_current_xlog_flush_location has been renamed to pg_current_wal_flush_lsn.

Pagination in ActiveRecord and SQL

Tagged activerecord, pagination  Languages ruby

Code:

class Pagination
  PER_PAGE ||= 10
  def self.call(relation:, page: 0, per_page: PER_PAGE)
    page = page.to_i
    per_page = per_page.to_i
    offset = page*per_page
    array = relation.offset(offset).limit(per_page+1).to_a
    has_previous_page = page > 0
    has_next_page = array.size > per_page
    pagination = OpenStruct.new(
      page: page,
      previous_page: has_previous_page ? page - 1 : nil,
      next_page: has_next_page ? page + 1 : nil
    )
    array = array[0..-2] if has_next_page
    [ array, pagination ]
  end
end

Example:

let(:relation) { Measurement.order("created_at DESC") }

it "paginates" do
  measurements, pagination = Pagination.call(relation: relation, per_page: 1, page: 0)
  assert_equal 1, measurements.size
  assert_equal OpenStruct.new(page: 0, previous_page: nil, next_page: nil), pagination
end

HTTP and HTTPS client example in Racket

Tagged client, http, https, racket  Languages racket
; HTTP example
(require net/http-client)
(http-sendrecv "google.com" "/" #:port 80)

; HTTPS example
(require net/http-client)
(http-sendrecv "google.com" "/" #:port 443 #:ssl? 'tls)

How to read Epub books on an Amazon Kindle

Tagged convert, epub, kindle, mobi  Languages bash

The Amazon Kindle does not support the Epub format, so to read Epub books on an Amazon Kindle you need to convert the book to the Mobi format.

Convert from Epub to Mobi

$ ./kindlegen your_book.epub

Send the book to your Kindle via email

For example: xxx_xxx@kindle.com

  • Send the book to your Kindle as an email attachment

Postgres SQL query for extracting and querying a JSON object containing an array of JSON objects

Tagged json, jsonb, postgres  Languages json, sql

We want to extract data by querying a JSON object (hash, dictionary, map, object) which contains an array of JSON objects:

{
  "responses": [
    {
      "patient": {
        "ssid": "101010-XXXX",
      },
      "patient": {
        "ssid": "070710-XXXX",
      }
   ]
 }
}

In Postgresql 9.4 and higher we can write the following query to query nested arrays of objects:

SELECT
   * 
FROM
   messages 
WHERE
   body -> 'responses' @> '[{"patient":[{"ssid":"070710-XXXX"}]}]';

In earlier versions of Postgres we can use the jsonb_array_elements function:

WITH json_messages AS (
 SELECT jsonb_array_elements(body#>'{responses}')->'patient'->>'ssid', id from messages
)
SELECT * FROM json_messages WHERE ssid = '010150-XXXX';

How to send an HL7 message using Ruby

Tagged hl7, ruby  Languages ruby
require 'socket'
a = TCPSocket.new('127.0.0.1', 2575)
message = File.read("src/test/resources/iso-8859-1.hl7")
puts "Wrote:\n#{message}"
a.write "\x0b#{message}\x1c\r"
puts "Received:\n" + a.recv(1024)
a.close