diff --git a/docs/database-queries.md b/docs/database-queries.md index 6805273..a55ac4f 100644 --- a/docs/database-queries.md +++ b/docs/database-queries.md @@ -7,7 +7,7 @@ Database queries in joy are very basic, they go a little something like this: Joy uses the `.env` file in your project dir (the one with the `project.janet` file in it) or your actual os environment variables and looks for `DATABASE_URL` or in joy `(env :database-url)` for the connection string. ```clojure -(import joy/db) +(import joy) (db/connect) ``` @@ -71,6 +71,18 @@ A more generic query (db/from :account :where {:email "email@example.com"} :order "created_at desc" :limit 10) ``` +Find row by primary key + +```clojure +(db/find :account 1) +``` + +Find first row by query + +```clojure +(db/first :account :where {:email "email@example.com"}) +``` + ## Conventions There are a few conventions you should follow: diff --git a/src/joy/db.janet b/src/joy/db.janet index 0afc97d..be76f96 100644 --- a/src/joy/db.janet +++ b/src/joy/db.janet @@ -25,7 +25,7 @@ Example: (import sqlite3) - (import joy/db) + (import joy) (db/with-connection "a-different-database.sqlite3" (sqlite3/eval "select 1;"))` @@ -86,7 +86,7 @@ Example: - (import joy/db) + (import joy) (db/query "select * from todos") @@ -112,7 +112,7 @@ Example: - (import joy/db) + (import joy) (db/execute "create table todo (id integer primary key, name text)") @@ -137,7 +137,7 @@ Example: - (import joy/db) + (import joy) (db/last-inserted "todo" 1) @@ -170,7 +170,7 @@ Example: - (import joy/db) + (import joy) (db/fetch [:todo 1]) @@ -190,7 +190,7 @@ Example: - (import joy/db) + (import joy) (db/fetch-all [:todo 1 :tag] :order "tag_name asc") @@ -210,7 +210,7 @@ Example: - (import joy/db) + (import joy) (db/from :todo :where {:completed true} :order "name" :limit 2) @@ -231,19 +231,19 @@ (query sql params))) -(defn find +(defn find-by `Takes a table name and optional args and returns either nil or the first row from the query. Example: - (import joy/db) + (import joy) - (db/find :todo :where {:completed true} :order "name") + (db/find-by :todo :where {:completed true} :order "name") # or - (db/find :todo :where {:completed true} :order "name desc") + (db/find-by :todo :where {:completed true} :order "name desc") => {:id 1 name "name" :completed true}` [table-name & args] @@ -254,6 +254,23 @@ (get rows 0))) +(defn find + `Takes a table name and optional args + and returns either nil or the first row by primary key. + + Example: + + (import joy) + + (db/find :todo 1) + + => {:id 1 name "name" :completed true}` + [table-name id] + (let [sql (sql/from table-name {:where {:id id} :limit 1}) + rows (query sql {:id id})] + (get rows 0))) + + (defn insert `Takes an optional db connection, a table name and a dictionary, inserts the dictionary as rows/columns into the database @@ -261,7 +278,7 @@ Example: - (import joy/db) + (import joy) (db/insert :todo {:name "name3"}) @@ -279,7 +296,7 @@ Example: - (import joy/db) + (import joy) (db/insert-all :todo [{:name "name4"} {:name "name5"}]) @@ -304,7 +321,7 @@ Example: - (import joy/db) + (import joy) (db/update :todo 4 {:name "new name 4"}) @@ -331,7 +348,7 @@ Example: - (import joy/db) + (import joy) (db/update-all :todo {:completed false} {:completed true}) @@ -358,7 +375,7 @@ Example: - (import joy/db) + (import joy) (db/delete :todo {:id 1}) @@ -379,7 +396,7 @@ Example: - (import joy/db) + (import joy) (db/delete-all :post :where {:draft true} :limit 1) diff --git a/test/joy/db-test.janet b/test/joy/db-test.janet index cc54f20..09a1a0d 100644 --- a/test/joy/db-test.janet +++ b/test/joy/db-test.janet @@ -1,10 +1,9 @@ (import tester :prefix "" :exit true) -(import "src/joy/db" :as db) -(import "src/joy/helper" :as helper) +(import "src/joy" :prefix "") (import cipher) # create a test .env file when this test is run -(helper/with-file [f ".env" :w] +(with-file [f ".env" :w] (file/write f (string/format "ENCRYPTION_KEY=%s\nJOY_ENV=development\nDATABASE_URL=test.sqlite3" (string (cipher/encryption-key))))) (db/connect) @@ -45,6 +44,14 @@ (get ? 0) (get ? :name))))) + (test "find" + (let [row (db/find :account (last-id))] + (= "new name" (get row :name)))) + + (test "find-by" + (let [row (db/find-by :account :where {:id (last-id)})] + (= "new name" (get row :name)))) + (test "delete" (let [account (db/delete :account (last-id))] (= "new name" (get account :name)))))