6 Commits

Author SHA1 Message Date
053d505988 fix for newest carp 2022-01-27 11:41:20 +01:00
1b87e7fec1 fix for new version of carp 2021-01-19 12:16:34 +01:00
a689c3ec85 version bump 2020-06-22 13:08:06 +02:00
f99c5dc329 Merge pull request #1 from TimDeve/update-to-latest-carp
Update to make lib work on latest Carp
2020-06-22 13:05:10 +02:00
Tim Dévé
f037790d07 Updates the docs so that the example work straight away
& Updates gendocs.carp so it behaved incorectly on latest carp
2020-06-19 21:32:32 +01:00
Tim Dévé
8818ec83ab Changes Char to CChar & adds implements interfaces
This makes sqlite work with current Carp at the time of commit
2020-06-19 21:14:10 +01:00
4 changed files with 201 additions and 159 deletions

View File

@@ -6,7 +6,7 @@ everything, but it tries to be useful.
## Installation ## Installation
```clojure ```clojure
(load "https://veitheller.de/git/carpentry/sqlite3@0.0.3") (load "git@git.veitheller.de:carpentry/sqlite3.git@0.0.6")
``` ```
## Usage ## Usage
@@ -15,7 +15,7 @@ The module `SQLite3` provides facilities for opening, closing, and querying
databases. databases.
```clojure ```clojure
(load "https://veitheller.de/git/carpentry/sqlite3@0.0.1") (load "git@git.veitheller.de:carpentry/sqlite3.git@0.0.6")
; opening DBs can fail, for the purposes of this example we ; opening DBs can fail, for the purposes of this example we
; ignore that ; ignore that

View File

@@ -9,8 +9,8 @@
<body> <body>
<div class="content"> <div class="content">
<div class="logo"> <div class="logo">
<a href="http://github.com/carp-lang/Carp"> <a href="">
<img src="logo.png"> <img src="">
</a> </a>
<div class="title"> <div class="title">
sqlite3 sqlite3
@@ -18,149 +18,180 @@
<div class="index"> <div class="index">
<ul> <ul>
<li> <li>
<a href="SQLite3.html"> <details>
SQLite3 <summary>
</a> <a href="SQLite3.html">
SQLite3
</a>
</summary>
<ul>
<li>
<details>
<summary>
<a href="SQLite3.Type.html">
Type
</a>
</summary>
<ul>
<li>
<a href="SQLite3.Type.SQLiteColumn.html">
SQLiteColumn
</a>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<h1> <div class="module">
SQLite3 <h1>
</h1> SQLite3
<div class="module-description"> </h1>
<p>is a simple high-level wrapper around SQLite3. It doesnt intend <div class="module-description">
<p>is a simple high-level wrapper around SQLite3. It doesnt intend
to wrap everything, but it tries to be useful.</p> to wrap everything, but it tries to be useful.</p>
<h2>Installation</h2> <h2>Installation</h2>
<pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/sqlite3@0.0.3&quot;) <pre><code class="language-clojure">(load &quot;git@veitheller.de:git/carpentry/sqlite3.git@0.0.6&quot;)
</code></pre> </code></pre>
<h2>Usage</h2> <h2>Usage</h2>
<p>The module <code>SQLite3</code> provides facilities for opening, closing, and querying <p>The module <code>SQLite3</code> provides facilities for opening, closing, and querying
databases.</p> databases.</p>
<pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/sqlite3@0.0.1&quot;) <pre><code class="language-clojure">(load &quot;git@veitheller.de:git/carpentry/sqlite3.git@0.0.6&quot;)
; opening DBs can fail, for the purposes of this example we ; opening DBs can fail, for the purposes of this example we
; ignore that ; ignore that
(let-do [db (Result.unsafe-from-success (SQLite3.open &quot;db&quot;))] (defn main []
; we can prepare statements (let-do [db (Result.unsafe-from-success (SQLite3.open &quot;db&quot;))]
(ignore ; Let's make sure our table is there
(SQLite3.query &amp;db &quot;INSERT INTO mytable VALUES (?1, ?2);&quot; (ignore
&amp;[(to-sqlite3 @&quot;hello&quot;) (to-sqlite3 100)])) (SQLite3.query &amp;db
; and query things &quot;CREATE TABLE IF NOT EXISTS mytable (name TEXT, age INT)&quot;
(println* &amp;(SQLite3.query &amp;db &quot;SELECT * from mytable;&quot; &amp;[])) &amp;[]))
(SQLite3.close db)
; we can prepare statements
(ignore
(SQLite3.query &amp;db
&quot;INSERT INTO mytable VALUES (?1, ?2);&quot;
&amp;[(to-sqlite3 @&quot;Carp&quot;) (to-sqlite3 4)]))
; and query things
(println* &amp;(SQLite3.query &amp;db &quot;SELECT * from mytable;&quot; &amp;[]))
(SQLite3.close db)))
</code></pre> </code></pre>
<p>Because <code>open</code> and <code>query</code> return <code>Result</code> types, we could also use <p>Because <code>open</code> and <code>query</code> return <code>Result</code> types, we could also use
combinators!</p> combinators!</p>
</div>
<div class="binder">
<a class="anchor" href="#SQLite">
<h3 id="SQLite">
SQLite
</h3>
</a>
<div class="description">
doc-stub
</div> </div>
<p class="sig"> <div class="binder">
a <a class="anchor" href="#SQLite">
</p> <h3 id="SQLite">
<span> SQLite
</h3>
</a>
<div class="description">
meta-stub
</div>
<p class="sig">
a
</p>
<span>
</span> </span>
<p class="doc"> <p class="doc">
<p>is the opaque database type. Youll need one of those to query <p>is the opaque database type. Youll need one of those to query
anything.</p> anything.</p>
<p>It can be obtained by using <a href="#open">open</a>.</p> <p>It can be obtained by using <a href="#open">open</a>.</p>
</p> </p>
</div>
<div class="binder">
<a class="anchor" href="#Type">
<h3 id="Type">
Type
</h3>
</a>
<div class="description">
module
</div> </div>
<p class="sig"> <div class="binder">
Module <a class="anchor" href="#Type">
</p> <h3 id="Type">
<span> <a href="SQLite3.Type.html">
Type
</a>
</h3>
</a>
<div class="description">
module
</div>
<p class="sig">
Module
</p>
<span>
</span> </span>
<p class="doc"> <p class="doc">
<p>represent all the SQLite types we can represent.</p>
<p>The constructors are <code>Null</code>, <code>Integer</code>, <code>Floating</code>, <code>Text</code>, and <code>Blob</code>. Most
primitive Carp types can be casted to appropriate SQLite types by using the
<code>to-sqlite3</code> interface.</p>
</p> </p>
</div>
<div class="binder">
<a class="anchor" href="#close">
<h3 id="close">
close
</h3>
</a>
<div class="description">
external
</div> </div>
<p class="sig"> <div class="binder">
(λ [SQLite] ()) <a class="anchor" href="#close">
</p> <h3 id="close">
<span> close
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(Fn [SQLite] ())
</p>
<span>
</span> </span>
<p class="doc"> <p class="doc">
<p>closes a database.</p> <p>closes a database.</p>
</p> </p>
</div>
<div class="binder">
<a class="anchor" href="#open">
<h3 id="open">
open
</h3>
</a>
<div class="description">
defn
</div> </div>
<p class="sig"> <div class="binder">
(λ [&amp;String] (Result SQLite String)) <a class="anchor" href="#open">
</p> <h3 id="open">
<pre class="args"> open
(open s) </h3>
</pre> </a>
<p class="doc"> <div class="description">
<p>opens a database with the filename <code>s</code>.</p> defn
</div>
<p class="sig">
(Fn [(Ref String a)] (Result SQLite String))
</p>
<pre class="args">
(open s)
</pre>
<p class="doc">
<p>opens a database with the filename <code>s</code>.</p>
<p>If it fails, we return an error message using <code>Result.Error</code>.</p> <p>If it fails, we return an error message using <code>Result.Error</code>.</p>
</p> </p>
</div>
<div class="binder">
<a class="anchor" href="#query">
<h3 id="query">
query
</h3>
</a>
<div class="description">
defn
</div> </div>
<p class="sig"> <div class="binder">
(λ [(Ref SQLite), &amp;String, (Ref (Array Type))] (Result (Array (Array Type)) String)) <a class="anchor" href="#query">
</p> <h3 id="query">
<pre class="args"> query
(query db s p) </h3>
</pre> </a>
<p class="doc"> <div class="description">
<p>queries the database <code>db</code> using the query <code>s</code> and the parameters defn
</div>
<p class="sig">
(Fn [(Ref SQLite a), (Ref String b), (Ref (Array SQLite3.Type) c)] (Result (Array (Array SQLite3.Type)) String))
</p>
<pre class="args">
(query db s p)
</pre>
<p class="doc">
<p>queries the database <code>db</code> using the query <code>s</code> and the parameters
<code>p</code>.</p> <code>p</code>.</p>
<p>If it fails, we return an error message using <code>Result.Error</code>.</p> <p>If it fails, we return an error message using <code>Result.Error</code>.</p>
</p> </p>
</div>
</div> </div>
</div> </div>
</body> </body>

View File

@@ -1,13 +1,10 @@
(load "sqlite3.carp") (load "sqlite3.carp")
(defndynamic gendocs [] (Project.config "title" "sqlite3")
(do (Project.config "docs-directory" "./docs/")
(Project.config "title" "sqlite3") (Project.config "docs-logo" "")
(Project.config "docs-directory" "./docs/") (Project.config "docs-styling" "style.css")
(Project.config "docs-logo" "") (Project.config "docs-generate-index" false)
(Project.config "docs-styling" "style.css") (save-docs SQLite3)
(Project.config "docs-generate-index" false)
(save-docs SQLite3)))
(gendocs)
(quit) (quit)

View File

@@ -7,7 +7,7 @@ to wrap everything, but it tries to be useful.
## Installation ## Installation
```clojure ```clojure
(load \"https://veitheller.de/git/carpentry/sqlite3@0.0.3\") (load \"git@veitheller.de:git/carpentry/sqlite3.git@0.0.6\")
``` ```
## Usage ## Usage
@@ -16,18 +16,27 @@ The module `SQLite3` provides facilities for opening, closing, and querying
databases. databases.
```clojure ```clojure
(load \"https://veitheller.de/git/carpentry/sqlite3@0.0.1\") (load \"git@veitheller.de:git/carpentry/sqlite3.git@0.0.6\")
; opening DBs can fail, for the purposes of this example we ; opening DBs can fail, for the purposes of this example we
; ignore that ; ignore that
(let-do [db (Result.unsafe-from-success (SQLite3.open \"db\"))] (defn main []
; we can prepare statements (let-do [db (Result.unsafe-from-success (SQLite3.open \"db\"))]
(ignore ; Let's make sure our table is there
(SQLite3.query &db \"INSERT INTO mytable VALUES (?1, ?2);\" (ignore
&[(to-sqlite3 @\"hello\") (to-sqlite3 100)])) (SQLite3.query &db
; and query things \"CREATE TABLE IF NOT EXISTS mytable (name TEXT, age INT)\"
(println* &(SQLite3.query &db \"SELECT * from mytable;\" &[])) &[]))
(SQLite3.close db)
; 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 Because `open` and `query` return `Result` types, we could also use
@@ -65,8 +74,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the
(Integer [Int]) (Integer [Int])
(Floating [Double]) (Floating [Double])
(Text [String]) (Text [String])
(Blob [String]) (Blob [String]))
)
(private SQLiteColumn) (private SQLiteColumn)
(hidden SQLiteColumn) (hidden SQLiteColumn)
@@ -78,8 +86,11 @@ primitive Carp types can be casted to appropriate SQLite types by using the
(register int (Fn [Int] SQLiteColumn) "SQLiteColumn_int") (register int (Fn [Int] SQLiteColumn) "SQLiteColumn_int")
(register float (Fn [Double] SQLiteColumn) "SQLiteColumn_float") (register float (Fn [Double] SQLiteColumn) "SQLiteColumn_float")
(register text (Fn [String] SQLiteColumn) "SQLiteColumn_text") (register text (Fn [String] SQLiteColumn) "SQLiteColumn_text")
(register blob (Fn [String] SQLiteColumn) "SQLiteColumn_blob") (register blob (Fn [String] SQLiteColumn) "SQLiteColumn_blob"))
)
(defn prn [s]
(SQLite3.Type.str s))
(implements prn SQLite3.Type.prn)
(defn to-sqlite3-internal [x] (defn to-sqlite3-internal [x]
(match x (match x
@@ -87,8 +98,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the
(Integer i) (SQLiteColumn.int i) (Integer i) (SQLiteColumn.int i)
(Floating f) (SQLiteColumn.float f) (Floating f) (SQLiteColumn.float f)
(Text s) (SQLiteColumn.text s) (Text s) (SQLiteColumn.text s)
(Blob s) (SQLiteColumn.blob s))) (Blob s) (SQLiteColumn.blob s))))
)
(defmodule SQLiteColumn (defmodule SQLiteColumn
(register tag (Fn [&SQLiteColumn] Int) "SQLiteColumn_tag") (register tag (Fn [&SQLiteColumn] Int) "SQLiteColumn_tag")
@@ -117,8 +127,7 @@ primitive Carp types can be casted to appropriate SQLite types by using the
a (Array.allocate l)] a (Array.allocate l)]
(for [i 0 l] (for [i 0 l]
(Array.aset-uninitialized! &a i (SQLiteColumn.to-carp (nth &r i)))) (Array.aset-uninitialized! &a i (SQLiteColumn.to-carp (nth &r i))))
a)) a)))
)
(private SQLiteRes) (private SQLiteRes)
(hidden SQLiteRes) (hidden SQLiteRes)
@@ -127,28 +136,27 @@ primitive Carp types can be casted to appropriate SQLite types by using the
(register ok? (Fn [&SQLiteRes] Bool) "SQLiteRes_is_ok") (register ok? (Fn [&SQLiteRes] Bool) "SQLiteRes_is_ok")
(register length (Fn [&SQLiteRes] Int) "SQLiteRes_length") (register length (Fn [&SQLiteRes] Int) "SQLiteRes_length")
(register nth (Fn [&SQLiteRes Int] SQLiteRow) "SQLiteRes_nth") (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] (defn to-array [r]
(let-do [l (length &r) (let-do [l (length &r)
a (Array.allocate l)] a (Array.allocate l)]
(for [i 0 l] (for [i 0 l]
(Array.aset-uninitialized! &a i (SQLiteRow.to-carp (nth &r i)))) (Array.aset-uninitialized! &a i (SQLiteRow.to-carp (nth &r i))))
a)) a)))
)
(private init) (private init)
(hidden init) (hidden init)
(register init (Fn [] SQLite)) (register init (Fn [] SQLite))
(private open-) (private open-)
(hidden 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-) (private exec-)
(hidden 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-) (private error-)
(hidden 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`. (doc open "opens a database with the filename `s`.
@@ -171,25 +179,31 @@ If it fails, we return an error message using `Result.Error`.")
(Result.Error (from-cstr (SQLiteRes.error r)))))) (Result.Error (from-cstr (SQLiteRes.error r))))))
(doc close "closes a database.") (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)) (definterface to-sqlite3 (Fn [a] SQLite3.Type))
(defmodule Bool (defmodule Bool
(defn to-sqlite3 [b] (SQLite3.Type.Integer (if b 1 0)))) (defn to-sqlite3 [b] (SQLite3.Type.Integer (if b 1 0)))
(implements to-sqlite3 Bool.to-sqlite3))
(defmodule Int (defmodule Int
(defn to-sqlite3 [i] (SQLite3.Type.Integer i))) (defn to-sqlite3 [i] (SQLite3.Type.Integer i))
(implements to-sqlite3 Int.to-sqlite3))
(defmodule Long (defmodule Long
(defn to-sqlite3 [l] (SQLite3.Type.Integer (to-int (the Long l))))) (defn to-sqlite3 [l] (SQLite3.Type.Integer (to-int (the Long l))))
(implements to-sqlite3 Long.to-sqlite3))
(defmodule Float (defmodule Float
(defn to-sqlite3 [f] (SQLite3.Type.Floating (Double.from-float f)))) (defn to-sqlite3 [f] (SQLite3.Type.Floating (Double.from-float f)))
(implements to-sqlite3 Float.to-sqlite3))
(defmodule Double (defmodule Double
(defn to-sqlite3 [d] (SQLite3.Type.Floating d))) (defn to-sqlite3 [d] (SQLite3.Type.Floating d))
(implements to-sqlite3 Double.to-sqlite3))
(defmodule String (defmodule String
(defn to-sqlite3 [s] (SQLite3.Type.Text s))) (defn to-sqlite3 [s] (SQLite3.Type.Text s))
(implements to-sqlite3 String.to-sqlite3))