1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/** -*-C-*-ish
SQLite interface library for Kaya
Copyright (C) 2006 Edwin Brady
This file is distributed under the terms of the GNU Lesser General
Public Licence. See COPYING for licence.
*/
"<summary>SQLite database interface module</summary>
<prose>This module allows querying of <link url='http://www.sqlite.org'>SQLite</link> database files, using the standard <moduleref>DB</moduleref> API.</prose>"
module SQLiteDB;
import Builtins;
// SQLite API suitable for use with the DB module.
// sqlite3_bind_*
import Prelude;
import public DB;
%include "sqlite_inter.h";
%imported "sqlite_inter";
%link "sqlite3";
"<summary>An SQLite database connection</summary>
<prose>This data type holds information about a database connection.
The type <code>SQLiteDB</code> is a type synonym for <code>DB::DBHandle<SQLiteConnection></code></prose>
<related><moduleref>DB</moduleref></related>"
abstract data SQLiteConnection = SQLiteCon(Ptr cdata);
type SQLiteDB = DBHandle<SQLiteConnection>;
"<argument>The String contains the error message</argument>
<summary>Database error</summary>
<prose>This Exception is thrown if an error occurs while opening or querying a database file.</prose>"
Exception SQLiteError(String msg);
"<summary>Tried to read too many rows</summary>
<prose>This Exception is thrown if you try to read more rows from an incremental database query than actually exist.</prose>"
Exception TooManyRows();
foreign "sqlite_inter.o" {
Ptr do_sqlite_connect(String info) = sqlite_connect;
Bool sqlite_ok(Ptr con) = sqlite_ok;
String sqlite_getError(Ptr con) = sqlite_getError;
Void sqlite_close(Ptr con) = sqlite_close;
Ptr sqlite_exec(Ptr con, String query) = sqlite_exec;
Ptr sqlite_incexec(Ptr con, String query) = sqlite_incexec;
[DBValue] sqlite_getrow(Ptr vm, Ptr res) = sqlite_getrow;
Void sqlite_discard(Ptr res) = sqlite_discard;
Ptr sqlite_execp(Ptr con, [Maybe<String>] params) = sqlite_execp;
Ptr do_sqliprepare(Ptr vm, Ptr con, String query) = sqlite_prepare;
[[DBValue]] sql_getrestable(Ptr pr) = sql_getrestable;
[String] sql_getcolnames(Ptr pr) = sql_getcolnames;
Int sql_numrows(Ptr pr) = sql_numrows;
Int sql_numcols(Ptr pr) = sql_numcols;
Int sql_resrc(Ptr pr) = sql_resrc;
}
"<argument name='fname'>The filename of the database</argument>
<summary>Open a database file.</summary>
<prose>Use this function to open the database file (creating it if it does not exist). You can then use the functions from <moduleref>DB</moduleref> to query the database.</prose>
<example>db = SQLiteDB::connect(\"site.db\");
res = exec(db,\"SELECT * FROM pagedata WHERE page_id = 10\");</example>
<related><moduleref>DB</moduleref></related>"
public SQLiteDB connect(String fname)
{
sqlc = do_sqlite_connect(fname);
con = SQLiteCon(sqlc);
if (sqlite_ok(sqlc)==false) {
throw(SQLiteError(sqlite_getError(sqlc)));
}
return DBh(con,
sqli_exec, sqli_incexec,
sqli_prepare, sqli_execp, defaultIncExecPrepared,
sqli_getrow, sqli_discard, sqli_close);
}
"Execute a query on the given connection."
DBResult sqli_exec(SQLiteConnection con, String query)
{
rc = sqlite_exec(con.cdata, query);
if (sql_resrc(rc)==0) {
dbvs = sql_getrestable(rc);
rows = sql_numrows(rc);
cols = sql_numcols(rc);
colnames = sql_getcolnames(rc);
return DBRes(dbvs, rows, cols, colnames, rc);
}
else {
throw(SQLiteError(sqlite_getError(con.cdata)));
}
}
DBIncResult<SQLiteConnection> sqli_incexec(SQLiteConnection con, String query, SQLiteDB dbc)
{
rc = sqlite_incexec(con.cdata, query);
if (sql_resrc(rc)==0) {
rows = sql_numrows(rc);
cols = sql_numcols(rc);
colnames = sql_getcolnames(rc);
return DBIncRes(dbc, rows, cols, colnames, rc);
}
else {
throw(SQLiteError(sqlite_getError(con.cdata)));
}
}
[DBValue] sqli_getrow(DBIncResult<SQLiteConnection> res) {
try {
return sqlite_getrow(getVM(),res.resptr);
} catch(InternalError(e)) {
if (e==0) {
throw(TooManyRows());
} else throw(InternalError(e));
}
}
Void sqli_discard(DBIncResult<SQLiteConnection> res) {
sqlite_discard(res.resptr);
}
"Close a connection to the database."
Void sqli_close(SQLiteConnection con)
{
sqlite_close(con.cdata);
}
DBStatement<SQLiteConnection> sqli_prepare(SQLiteDB con, String query) {
try {
return DBStatement(con,do_sqliprepare(getVM,con.handle.cdata,query));
} catch(InternalError(e)) {
throw(SQLiteError(sqlite_getError(con.handle.cdata)));
}
}
DBResult sqli_execp(DBStatement<SQLiteConnection> prep, [Maybe<String>] params) {
rc = sqlite_execp(prep.statement, params);
if (sql_resrc(rc)==0) {
dbvs = sql_getrestable(rc);
rows = sql_numrows(rc);
cols = sql_numcols(rc);
colnames = sql_getcolnames(rc);
return DBRes(dbvs, rows, cols, colnames, rc);
}
else {
throw(SQLiteError(sqlite_getError(prep.con.handle.cdata)));
}
}
|