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
```clojure
(load "https://veitheller.de/git/carpentry/sqlite3@0.0.3")
(load "git@git.veitheller.de:carpentry/sqlite3.git@0.0.6")
```
## Usage
@@ -15,7 +15,7 @@ The module `SQLite3` provides facilities for opening, closing, and querying
databases.
```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
; ignore that

View File

@@ -9,8 +9,8 @@
<body>
<div class="content">
<div class="logo">
<a href="http://github.com/carp-lang/Carp">
<img src="logo.png">
<a href="">
<img src="">
</a>
<div class="title">
sqlite3
@@ -18,149 +18,180 @@
<div class="index">
<ul>
<li>
<a href="SQLite3.html">
SQLite3
</a>
<details>
<summary>
<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>
</ul>
</div>
</div>
<h1>
SQLite3
</h1>
<div class="module-description">
<p>is a simple high-level wrapper around SQLite3. It doesnt intend
<div class="module">
<h1>
SQLite3
</h1>
<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>
<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>
<h2>Usage</h2>
<p>The module <code>SQLite3</code> provides facilities for opening, closing, and querying
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
; ignore that
(let-do [db (Result.unsafe-from-success (SQLite3.open &quot;db&quot;))]
; we can prepare statements
(ignore
(SQLite3.query &amp;db &quot;INSERT INTO mytable VALUES (?1, ?2);&quot;
&amp;[(to-sqlite3 @&quot;hello&quot;) (to-sqlite3 100)]))
; and query things
(println* &amp;(SQLite3.query &amp;db &quot;SELECT * from mytable;&quot; &amp;[]))
(SQLite3.close db)
(defn main []
(let-do [db (Result.unsafe-from-success (SQLite3.open &quot;db&quot;))]
; Let's make sure our table is there
(ignore
(SQLite3.query &amp;db
&quot;CREATE TABLE IF NOT EXISTS mytable (name TEXT, age INT)&quot;
&amp;[]))
; 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>
<p>Because <code>open</code> and <code>query</code> return <code>Result</code> types, we could also use
combinators!</p>
</div>
<div class="binder">
<a class="anchor" href="#SQLite">
<h3 id="SQLite">
SQLite
</h3>
</a>
<div class="description">
doc-stub
</div>
<p class="sig">
a
</p>
<span>
</span>
<p class="doc">
<p>is the opaque database type. Youll need one of those to query
<div class="binder">
<a class="anchor" href="#SQLite">
<h3 id="SQLite">
SQLite
</h3>
</a>
<div class="description">
meta-stub
</div>
<p class="sig">
a
</p>
<span>
</span>
<p class="doc">
<p>is the opaque database type. Youll need one of those to query
anything.</p>
<p>It can be obtained by using <a href="#open">open</a>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#Type">
<h3 id="Type">
Type
</h3>
</a>
<div class="description">
module
</p>
</div>
<p class="sig">
Module
</p>
<span>
</span>
<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>
<div class="binder">
<a class="anchor" href="#Type">
<h3 id="Type">
<a href="SQLite3.Type.html">
Type
</a>
</h3>
</a>
<div class="description">
module
</div>
<p class="sig">
Module
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#close">
<h3 id="close">
close
</h3>
</a>
<div class="description">
external
</div>
<p class="sig">
(Fn [SQLite] ())
</p>
<span>
</span>
<p class="doc">
<p>closes a database.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#close">
<h3 id="close">
close
</h3>
</a>
<div class="description">
external
</p>
</div>
<p class="sig">
(λ [SQLite] ())
</p>
<span>
</span>
<p class="doc">
<p>closes a database.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#open">
<h3 id="open">
open
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [&amp;String] (Result SQLite String))
</p>
<pre class="args">
(open s)
</pre>
<p class="doc">
<p>opens a database with the filename <code>s</code>.</p>
<div class="binder">
<a class="anchor" href="#open">
<h3 id="open">
open
</h3>
</a>
<div class="description">
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>
</div>
<div class="binder">
<a class="anchor" href="#query">
<h3 id="query">
query
</h3>
</a>
<div class="description">
defn
</p>
</div>
<p class="sig">
(λ [(Ref SQLite), &amp;String, (Ref (Array Type))] (Result (Array (Array 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
<div class="binder">
<a class="anchor" href="#query">
<h3 id="query">
query
</h3>
</a>
<div class="description">
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>
<p>If it fails, we return an error message using <code>Result.Error</code>.</p>
</p>
</p>
</div>
</div>
</div>
</body>

View File

@@ -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)

View File

@@ -7,7 +7,7 @@ to wrap everything, but it tries to be useful.
## Installation
```clojure
(load \"https://veitheller.de/git/carpentry/sqlite3@0.0.3\")
(load \"git@veitheller.de:git/carpentry/sqlite3.git@0.0.6\")
```
## Usage
@@ -16,18 +16,27 @@ The module `SQLite3` provides facilities for opening, closing, and querying
databases.
```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
; 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
@@ -65,8 +74,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 +86,11 @@ 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 prn [s]
(SQLite3.Type.str s))
(implements prn SQLite3.Type.prn)
(defn to-sqlite3-internal [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)
(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 +127,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 +136,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 +179,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))
(definterface to-sqlite3 (Fn [a] SQLite3.Type))
(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
(defn to-sqlite3 [i] (SQLite3.Type.Integer i)))
(defn to-sqlite3 [i] (SQLite3.Type.Integer i))
(implements to-sqlite3 Int.to-sqlite3))
(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
(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
(defn to-sqlite3 [d] (SQLite3.Type.Floating d)))
(defn to-sqlite3 [d] (SQLite3.Type.Floating d))
(implements to-sqlite3 Double.to-sqlite3))
(defmodule String
(defn to-sqlite3 [s] (SQLite3.Type.Text s)))
(defn to-sqlite3 [s] (SQLite3.Type.Text s))
(implements to-sqlite3 String.to-sqlite3))