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

How to parse OBX segments from an ORU-01 HL7 message using Java and HAPI

Tagged hapi, hl7, java, obx, oru  Languages java, xml

Tested with HAPI 2.3:

import ca.uhn.hl7v2.model.v23.message.ORU_R01;
import ca.uhn.hl7v2.model.v23.group.*;
import ca.uhn.hl7v2.model.v23.segment.OBX;
import ca.uhn.hl7v2.model.v23.segment.OBR;
import ca.uhn.hl7v2.model.Varies;
import org.junit.BeforeClass;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.PipeParser;
import ca.uhn.hl7v2.util.Terser;

/*
 * An HL7 message has the following components:
 *
 * MSH - Message Header Segment
 * RESPONSE (repeating)
 *   PATIENT
 *     PID - Patient Identification Segment
 *     PV1 – Patient Visit Segment
 *   ORDER OBSERVATION (repeating)
 *     OBR - Observation Request Segment
 *       ORC - Common Order Segment
 *       OBR - Observation Request Segment
 *       OBX – Observation Segment (repeating)
 *
 */

PipeParser pipeParser = new PipeParser();
pipeParser.setValidationContext(new ca.uhn.hl7v2.validation.impl.NoValidation());
Message message = pipeParser.parse(m);
ORU_R01 oru = (ORU_R01) message;
MSH msh = oru.getMSH();
String sendingApp = msh.getSendingApplication().encode();
String sendingFacility = msh.getSendingFacility().encode();
//
// ORU_R01_RESPONSE group structure (a Group object)
//
// 1: ORU_R01_PATIENT (a Group object) optional
// 2: ORU_R01_ORDER_OBSERVATION (a Group object) repeating
//
// See https://hapifhir.github.io/hapi-hl7v2/v23/apidocs/src-html/ca/uhn/hl7v2/model/v23/group/ORU_R01_RESPONSE.html
//
for (ORU_R01_RESPONSE response : oru.getRESPONSEAll()) {
  //
  // ORU_R01_ORDER_OBSERVATION group structure (a Group object)
  //
  // 1: ORC (Common order segment) optional
  // 2: OBR (Observation request segment)
  // 3: NTE (Notes and comments segment) optional repeating
  // 4: ORU_R01_OBSERVATION (a Group object) repeating
  // 5: CTI (Clinical Trial Identification) optional repeating
  //
  // See https://hapifhir.github.io/hapi-hl7v2/v23/apidocs/src-html/ca/uhn/hl7v2/model/v23/group/ORU_R01_ORDER_OBSERVATION.html
  //
  for (ORU_R01_ORDER_OBSERVATION orderObservation : response.getORDER_OBSERVATIONAll()) {
    OBR obr = orderObservation.getOBR();
    String fillerOrderNumber = obr.getObr3_FillerOrderNumber().encode();
    //
    // ORU_R01_OBSERVATION group structure (a Group object)
    //
    // 1: OBX (Observation segment) optional
    // 2: NTE (Notes and comments segment) optional repeating
    //
    // See https://hapifhir.github.io/hapi-hl7v2/v23/apidocs/src-html/ca/uhn/hl7v2/model/v23/group/ORU_R01_OBSERVATION.html
    //
    for (ORU_R01_OBSERVATION observation : orderObservation.getOBSERVATIONAll()) {
      //
      // HL7 OBX message segment (Observation segment)
      //
      // https://hapifhir.github.io/hapi-hl7v2/v23/apidocs/src-html/ca/uhn/hl7v2/model/v23/segment/OBX.html
      //
      OBX obx = observation.getOBX();
      String type = obx.getObx3_ObservationIdentifier().getCe2_Text().getValue();
      String status = obx.getObservResultStatus().getValue();
      for (Varies varies : obx.getObx5_ObservationValue()) {
        String value = varies.encode();
        log.info("value {} type {} status {}", value, type, status);
      }
    }
  }
}
    <dependency>
      <groupId>ca.uhn.hapi</groupId>
      <artifactId>hapi-base</artifactId>
      <version>${hapi.version.stable}</version>
    </dependency>
    <dependency>
      <groupId>ca.uhn.hapi</groupId>
      <artifactId>hapi-structures-v23</artifactId>
      <version>${hapi.version.stable}</version>
    </dependency>

Use the HAPI test panel to inspect and find the names of elements, e.g. PID-3-4: https://hapifhir.github.io/hapi-hl7v2/hapi-testpanel/install.html

How to use LATERAL as a for loop in Postgres

Tagged lateral, loop, postgres  Languages sql

This example shows how to use LATERAL as a for loop in Postgres. The query will perform a lateral subquery for each month. The subquery returns the number of active courses during each month.

-- A list of months and their start and end timestamps
WITH months AS (
  SELECT start, start + (interval '1' month) - (interval '1' second) AS end FROM (
    SELECT generate_series(DATE('2010-01-01'), DATE('2010-12-01'), interval '1 month') AS start
  ) months
)
-- For each month, run a query that returns the number of active courses during that month
SELECT * FROM months AS m
LEFT JOIN LATERAL (
  SELECT count(id)
  FROM courses AS c
  WHERE
    (c.start <= m.end AND c.start >= m.start) OR
    (c.end <= m.end AND c.end IS NULL)
) AS results ON TRUE;

How to generate a series with the start and end dates of months with Postgres

Tagged generate_series, months, sql  Languages sql
WITH m AS (
  SELECT generate_series(DATE('2010-01-01'), DATE('2010-12-01'), interval '1 month') AS start
)
SELECT m.start, m.start + (interval '1' month) - (interval '1' second) AS end FROM m;
┌────────────────────────┬────────────────────────┐
│         start          │          end           │
├────────────────────────┼────────────────────────┤
│ 2010-01-01 00:00:00+02 │ 2010-01-31 23:59:59+02 │
│ 2010-02-01 00:00:00+02 │ 2010-02-28 23:59:59+02 │
│ 2010-03-01 00:00:00+02 │ 2010-03-31 23:59:59+03 │
│ 2010-04-01 00:00:00+03 │ 2010-04-30 23:59:59+03 │
│ 2010-05-01 00:00:00+03 │ 2010-05-31 23:59:59+03 │
│ 2010-06-01 00:00:00+03 │ 2010-06-30 23:59:59+03 │
│ 2010-07-01 00:00:00+03 │ 2010-07-31 23:59:59+03 │
│ 2010-08-01 00:00:00+03 │ 2010-08-31 23:59:59+03 │
│ 2010-09-01 00:00:00+03 │ 2010-09-30 23:59:59+03 │
│ 2010-10-01 00:00:00+03 │ 2010-10-31 23:59:59+02 │
│ 2010-11-01 00:00:00+02 │ 2010-11-30 23:59:59+02 │
│ 2010-12-01 00:00:00+02 │ 2010-12-31 23:59:59+02 │
└────────────────────────┴────────────────────────┘

Same query without the CTE:

SELECT start, start + (interval '1' month) - (interval '1' second) AS end FROM (
  SELECT generate_series(DATE('2010-01-01'), DATE('2010-12-01'), interval '1 month') AS start
) months;