apa512 / clj-rethinkdb

Eclipse Public License 1.0
204 stars 42 forks source link

Documentation for how to provide optargs #115

Closed aphyr closed 8 years ago

aphyr commented 8 years ago

Hi there! I'm trying to do an upsert, and the rethink team advised me to pass the conflict: "update" option to an insert command. I can't find an example of how optargs work anywhere in the docs, and reading the source has been a little unclear. I think it's a... map? Of strings to strings? Hit a lot of vague type errors and settled on

(r/insert (r/table (r/db db) tbl)
    {:val value}
    {"conflict" "update"})

which expands to

{:rethinkdb.query-builder/term :INSERT,
 :rethinkdb.query-builder/args
 [{:rethinkdb.query-builder/term :TABLE,
   :rethinkdb.query-builder/args
   [{:rethinkdb.query-builder/term :DB,
     :rethinkdb.query-builder/args ["jepsen"],
     :rethinkdb.query-builder/optargs nil}
    "cas"],
   :rethinkdb.query-builder/optargs nil}
  {:val 3}],
 :rethinkdb.query-builder/optargs {"conflict" "update"}}

That doesn't throw, but it also doesn't seem to do an upsert. Is it possible I'm invoking optargs incorrectly?

aphyr commented 8 years ago

No sooner than one files an issue than one's mistake becomes apparent. I forgot an :id key, so it'd autogenerate one for me. Might be cool to show an example invocation somewhere in the docs, but I think I'm good to go. :)

danielcompton commented 8 years ago

Hey sorry for the missing docs. You can also write that query as

(-> (r/db "test")
    (r/table "authors")
    (r/insert {:id "2" :val "a"} {:conflict :update})
    (r/run (r/connect)))
=> {:deleted 0, :errors 0, :inserted 1, :replaced 0, :skipped 0, :unchanged 0}

Optargs are maps and can use either strings or keywords, they both end up as strings when sent to the DB. clj-rethinkdb tries to stay as close as possible to the official JavaScript driver API.

I've also pushed some more docs to explain this further, let me know if they're helpful.