Skip to content

Instantly share code, notes, and snippets.

@gtod
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gtod/2f17dde3fc8eafc02058 to your computer and use it in GitHub Desktop.
Save gtod/2f17dde3fc8eafc02058 to your computer and use it in GitHub Desktop.

On cl-rethinkdb *sequence-type*

According to https://github.com/orthecreedence/cl-rethinkdb#sequence-type this may be set to :list or :array.

Firstly, to be very clear, *sequence-type* only determines the type of sequences that cl-rethinkdb returns to you. It does not determine what types of sequences (lists or vectors in common lisp) that you may send to cl-rethinkdb for inserting or updating.

So say we want to populate an array of arrays (JSON types) in some rethinkdb document. Two possible methods look like:

(r:r
  (:insert (:table "foo") 
           '(("pickups" . #(#("141 Smith St" "Somewhere") #("11 Jones Rd" "Somewhereelse"))))))

(r:r
  (:insert (:table "foo") 
           '(("pickups" . '(("241 Smith St" "Somewhere") ("21 Jones Rd" "Somewhereelse"))))))

If we now do (r:r (:table "foo")) we get back (serialized to JSON for display):

[
    {
        "pickups":[
            [
                "141 Smith St",
                "Somewhere"
            ],
            [
                "11 Jones Rd",
                "Somewhereelse"
            ]
        ],
        "id":"c9428e79-afbb-4466-8671-286728b581a9"
    },
    {
        "pickups":[
            null,
            {
                "241 Smith St":[
                    "Somewhere"
                ],
                "21 Jones Rd":[
                    "Somewhereelse"
                ]
            }
        ],
        "id":"e525b5d2-6a2e-47d9-a428-cd28c876f2ed"
    }
]

The problem with the second method is that your (common lisp) list of two elements (each element being itself a list of two elements) has been interpreted as an association list by cl-rethinkdb, which means it wants to make a JSON object out of it, which is clearly not our intention. The lesson then is to stick to (common lisp) vectors for insertions.

But the trap is that if you have *sequence-type* set to :list then if you now run

(r:r
  (:get (:table "foo") "c9428e79-afbb-4466-8671-286728b581a9"))        

you get back (if *object-type* is :hash):

#<HASH-TABLE 402013CAA3>
--------------------
Count: 2
Test: EQUAL
Contents: 
"id" = "c9428e79-afbb-4466-8671-286728b581a9"
"pickups" = (("141 Smith St" "Somewhere") ("11 Jones Rd" "Somewhereelse"))

This is fine for perusing but say you want to round trip it back to the server (ie. insert/update some document using the above data, from the REPL). Well that simply won't work for the reason we demonstrated above: the (common lisp) list of lists which you want to be understood as a (JSON) array of arrays will be misunderstood as an alist... This is one reason then why you might want to stick to *sequence-type* :array...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment