From 8818ec83ab642b5fec91c3f583f66b47eb999f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=A9v=C3=A9?= Date: Fri, 19 Jun 2020 21:14:10 +0100 Subject: [PATCH 1/2] Changes Char to CChar & adds implements interfaces This makes sqlite work with current Carp at the time of commit --- sqlite3.carp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/sqlite3.carp b/sqlite3.carp index 8f4891a..e90508a 100644 --- a/sqlite3.carp +++ b/sqlite3.carp @@ -16,7 +16,7 @@ The module `SQLite3` provides facilities for opening, closing, and querying databases. ```clojure -(load \"https://veitheller.de/git/carpentry/sqlite3@0.0.1\") +(load \"https://veitheller.de/git/carpentry/sqlite3@0.0.3\") ; opening DBs can fail, for the purposes of this example we ; ignore that @@ -65,8 +65,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the (Integer [Int]) (Floating [Double]) (Text [String]) - (Blob [String]) - ) + (Blob [String])) (private SQLiteColumn) (hidden SQLiteColumn) @@ -78,8 +77,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the (register int (Fn [Int] SQLiteColumn) "SQLiteColumn_int") (register float (Fn [Double] SQLiteColumn) "SQLiteColumn_float") (register text (Fn [String] SQLiteColumn) "SQLiteColumn_text") - (register blob (Fn [String] SQLiteColumn) "SQLiteColumn_blob") - ) + (register blob (Fn [String] SQLiteColumn) "SQLiteColumn_blob")) (defn to-sqlite3-internal [x] (match x @@ -87,8 +85,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the (Integer i) (SQLiteColumn.int i) (Floating f) (SQLiteColumn.float f) (Text s) (SQLiteColumn.text s) - (Blob s) (SQLiteColumn.blob s))) - ) + (Blob s) (SQLiteColumn.blob s)))) (defmodule SQLiteColumn (register tag (Fn [&SQLiteColumn] Int) "SQLiteColumn_tag") @@ -117,8 +114,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the a (Array.allocate l)] (for [i 0 l] (Array.aset-uninitialized! &a i (SQLiteColumn.to-carp (nth &r i)))) - a)) - ) + a))) (private SQLiteRes) (hidden SQLiteRes) @@ -127,28 +123,27 @@ primitive Carp types can be casted to appropriate SQLite types by using the (register ok? (Fn [&SQLiteRes] Bool) "SQLiteRes_is_ok") (register length (Fn [&SQLiteRes] Int) "SQLiteRes_length") (register nth (Fn [&SQLiteRes Int] SQLiteRow) "SQLiteRes_nth") - (register error (Fn [SQLiteRes] (Ptr Char)) "SQLiteRes_error") + (register error (Fn [SQLiteRes] (Ptr CChar)) "SQLiteRes_error") (defn to-array [r] (let-do [l (length &r) a (Array.allocate l)] (for [i 0 l] (Array.aset-uninitialized! &a i (SQLiteRow.to-carp (nth &r i)))) - a)) - ) + a))) (private init) (hidden init) (register init (Fn [] SQLite)) (private open-) (hidden open-) - (register open- (Fn [&SQLite (Ptr Char)] Int) "SQLite3_open_c") + (register open- (Fn [&SQLite (Ptr CChar)] Int) "SQLite3_open_c") (private exec-) (hidden exec-) - (register exec- (Fn [&SQLite (Ptr Char) &(Array SQLiteColumn)] SQLiteRes) "SQLite3_exec_c") + (register exec- (Fn [&SQLite (Ptr CChar) &(Array SQLiteColumn)] SQLiteRes) "SQLite3_exec_c") (private error-) (hidden error-) - (register error- (Fn [SQLite] (Ptr Char)) "SQLite3_error") + (register error- (Fn [SQLite] (Ptr CChar)) "SQLite3_error") (doc open "opens a database with the filename `s`. @@ -171,25 +166,31 @@ If it fails, we return an error message using `Result.Error`.") (Result.Error (from-cstr (SQLiteRes.error r)))))) (doc close "closes a database.") - (register close (Fn [SQLite] ()) "SQLite3_close_c") -) + (register close (Fn [SQLite] ()) "SQLite3_close_c")) (definterface to-sqlite3 (Fn [a] SQLIte3.Type)) (defmodule Bool + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [b] (SQLite3.Type.Integer (if b 1 0)))) (defmodule Int + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [i] (SQLite3.Type.Integer i))) (defmodule Long + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [l] (SQLite3.Type.Integer (to-int (the Long l))))) (defmodule Float + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [f] (SQLite3.Type.Floating (Double.from-float f)))) (defmodule Double + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [d] (SQLite3.Type.Floating d))) (defmodule String + (implements to-sqlite3 to-sqlite3) (defn to-sqlite3 [s] (SQLite3.Type.Text s))) + From f037790d07e2d30267a5d8737c58baa947be08db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=A9v=C3=A9?= Date: Fri, 19 Jun 2020 21:32:32 +0100 Subject: [PATCH 2/2] Updates the docs so that the example work straight away & Updates gendocs.carp so it behaved incorectly on latest carp --- docs/SQLite3.html | 33 +++++++++++++++++++++------------ gendocs.carp | 15 ++++++--------- sqlite3.carp | 25 +++++++++++++++++-------- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/docs/SQLite3.html b/docs/SQLite3.html index 1b5e035..d7bd998 100644 --- a/docs/SQLite3.html +++ b/docs/SQLite3.html @@ -37,18 +37,27 @@ to wrap everything, but it tries to be useful.

Usage

The module SQLite3 provides facilities for opening, closing, and querying databases.

-
(load "https://veitheller.de/git/carpentry/sqlite3@0.0.1")
+
(load "https://veitheller.de/git/carpentry/sqlite3@0.0.3")
 
 ; opening DBs can fail, for the purposes of this example we
 ; ignore that
-(let-do [db (Result.unsafe-from-success (SQLite3.open "db"))]
-  ; we can prepare statements
-  (ignore
-    (SQLite3.query &db "INSERT INTO mytable VALUES (?1, ?2);"
-                   &[(to-sqlite3 @"hello") (to-sqlite3 100)]))
-  ; and query things
-  (println* &(SQLite3.query &db "SELECT * from mytable;" &[]))
-  (SQLite3.close db)
+(defn main []
+  (let-do [db (Result.unsafe-from-success (SQLite3.open "db"))]
+    ; Let's make sure our table is there
+    (ignore
+       (SQLite3.query &db
+                      "CREATE TABLE IF NOT EXISTS mytable (name TEXT, age INT)"
+                      &[]))
+
+    ; we can prepare statements
+    (ignore
+       (SQLite3.query &db
+                      "INSERT INTO mytable VALUES (?1, ?2);"
+                      &[(to-sqlite3 @"Carp") (to-sqlite3 4)]))
+
+    ; and query things
+    (println* &(SQLite3.query &db "SELECT * from mytable;" &[]))
+    (SQLite3.close db)))
 

Because open and query return Result types, we could also use combinators!

@@ -109,7 +118,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the external

- (λ [SQLite] ()) + (Fn [SQLite] ())

@@ -129,7 +138,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the defn

- (λ [&String] (Result SQLite String)) + (Fn [(Ref String a)] (Result SQLite String))

                     (open s)
@@ -150,7 +159,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the
                     defn
                 
                 

- (λ [(Ref SQLite), &String, (Ref (Array Type))] (Result (Array (Array Type)) String)) + (Fn [(Ref SQLite a), (Ref String b), (Ref (Array Type) c)] (Result (Array (Array Type)) String))

                     (query db s p)
diff --git a/gendocs.carp b/gendocs.carp
index 3e688e5..6fa34b4 100644
--- a/gendocs.carp
+++ b/gendocs.carp
@@ -1,13 +1,10 @@
 (load "sqlite3.carp")
 
-(defndynamic gendocs []
-       (do
-         (Project.config "title" "sqlite3")
-         (Project.config "docs-directory" "./docs/")
-         (Project.config "docs-logo" "")
-         (Project.config "docs-styling" "style.css")
-         (Project.config "docs-generate-index" false)
-         (save-docs SQLite3)))
+(Project.config "title" "sqlite3")
+(Project.config "docs-directory" "./docs/")
+(Project.config "docs-logo" "")
+(Project.config "docs-styling" "style.css")
+(Project.config "docs-generate-index" false)
+(save-docs SQLite3)
 
-(gendocs)
 (quit)
diff --git a/sqlite3.carp b/sqlite3.carp
index e90508a..245972f 100644
--- a/sqlite3.carp
+++ b/sqlite3.carp
@@ -20,14 +20,23 @@ databases.
 
 ; opening DBs can fail, for the purposes of this example we
 ; ignore that
-(let-do [db (Result.unsafe-from-success (SQLite3.open \"db\"))]
-  ; we can prepare statements
-  (ignore
-    (SQLite3.query &db \"INSERT INTO mytable VALUES (?1, ?2);\"
-                   &[(to-sqlite3 @\"hello\") (to-sqlite3 100)]))
-  ; and query things
-  (println* &(SQLite3.query &db \"SELECT * from mytable;\" &[]))
-  (SQLite3.close db)
+(defn main []
+  (let-do [db (Result.unsafe-from-success (SQLite3.open \"db\"))]
+    ; Let's make sure our table is there
+    (ignore
+       (SQLite3.query &db
+                      \"CREATE TABLE IF NOT EXISTS mytable (name TEXT, age INT)\"
+                      &[]))
+
+    ; we can prepare statements
+    (ignore
+       (SQLite3.query &db
+                      \"INSERT INTO mytable VALUES (?1, ?2);\"
+                      &[(to-sqlite3 @\"Carp\") (to-sqlite3 4)]))
+
+    ; and query things
+    (println* &(SQLite3.query &db \"SELECT * from mytable;\" &[]))
+    (SQLite3.close db)))
 ```
 
 Because `open` and `query` return `Result` types, we could also use