2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "sqlite_database.h"
23 #include <utils/mutex.h>
25 typedef struct private_sqlite_database_t private_sqlite_database_t
;
28 * private data of sqlite_database
30 struct private_sqlite_database_t
{
35 sqlite_database_t
public;
38 * sqlite database connection
43 * mutex used to lock execute()
49 * Create and run a sqlite stmt using a sql string and args
51 static sqlite3_stmt
* run(private_sqlite_database_t
*this, char *sql
,
55 int params
, i
, res
= SQLITE_OK
;
57 if (sqlite3_prepare_v2(this->db
, sql
, -1, &stmt
, NULL
) == SQLITE_OK
)
59 params
= sqlite3_bind_parameter_count(stmt
);
60 for (i
= 1; i
<= params
; i
++)
62 switch (va_arg(*args
, db_type_t
))
66 res
= sqlite3_bind_int(stmt
, i
, va_arg(*args
, int));
71 res
= sqlite3_bind_int64(stmt
, i
, va_arg(*args
, u_int
));
76 const char *text
= va_arg(*args
, const char*);
77 res
= sqlite3_bind_text(stmt
, i
, text
, -1, SQLITE_STATIC
);
82 chunk_t c
= va_arg(*args
, chunk_t
);
83 res
= sqlite3_bind_blob(stmt
, i
, c
.ptr
, c
.len
, SQLITE_STATIC
);
88 res
= sqlite3_bind_double(stmt
, i
, va_arg(*args
, double));
93 res
= sqlite3_bind_null(stmt
, i
);
102 if (res
!= SQLITE_OK
)
108 if (res
!= SQLITE_OK
)
110 sqlite3_finalize(stmt
);
117 /** implements enumerator_t */
119 /** associated sqlite statement */
121 /** number of result columns */
125 } sqlite_enumerator_t
;
128 * destroy a sqlite enumerator
130 static void sqlite_enumerator_destroy(sqlite_enumerator_t
*this)
132 sqlite3_finalize(this->stmt
);
138 * Implementation of database.query().enumerate
140 static bool sqlite_enumerator_enumerate(sqlite_enumerator_t
*this, ...)
145 if (sqlite3_step(this->stmt
) != SQLITE_ROW
)
149 va_start(args
, this);
150 for (i
= 0; i
< this->count
; i
++)
152 switch (this->columns
[i
])
156 int *value
= va_arg(args
, int*);
157 *value
= sqlite3_column_int(this->stmt
, i
);
162 u_int
*value
= va_arg(args
, u_int
*);
163 *value
= (u_int
)sqlite3_column_int64(this->stmt
, i
);
168 const unsigned char **value
= va_arg(args
, const unsigned char**);
169 *value
= sqlite3_column_text(this->stmt
, i
);
174 chunk_t
*chunk
= va_arg(args
, chunk_t
*);
175 chunk
->len
= sqlite3_column_bytes(this->stmt
, i
);
176 chunk
->ptr
= (u_char
*)sqlite3_column_blob(this->stmt
, i
);
181 double *value
= va_arg(args
, double*);
182 *value
= sqlite3_column_double(this->stmt
, i
);
194 * Implementation of database_t.query.
196 static enumerator_t
* query(private_sqlite_database_t
*this, char *sql
, ...)
200 sqlite_enumerator_t
*enumerator
= NULL
;
205 stmt
= run(this, sql
, &args
);
208 enumerator
= malloc_thing(sqlite_enumerator_t
);
209 enumerator
->public.enumerate
= (void*)sqlite_enumerator_enumerate
;
210 enumerator
->public.destroy
= (void*)sqlite_enumerator_destroy
;
211 enumerator
->stmt
= stmt
;
212 enumerator
->count
= sqlite3_column_count(stmt
);
213 enumerator
->columns
= malloc(sizeof(db_type_t
) * enumerator
->count
);
214 for (i
= 0; i
< enumerator
->count
; i
++)
216 enumerator
->columns
[i
] = va_arg(args
, db_type_t
);
220 return (enumerator_t
*)enumerator
;
224 * Implementation of database_t.execute.
226 static int execute(private_sqlite_database_t
*this, int *rowid
, char *sql
, ...)
232 /* we need a lock to get our rowid/changes correctly */
233 this->mutex
->lock(this->mutex
);
235 stmt
= run(this, sql
, &args
);
239 if (sqlite3_step(stmt
) == SQLITE_DONE
)
243 *rowid
= sqlite3_last_insert_rowid(this->db
);
245 affected
= sqlite3_changes(this->db
);
247 sqlite3_finalize(stmt
);
249 this->mutex
->unlock(this->mutex
);
254 * Implementation of database_t.destroy
256 static void destroy(private_sqlite_database_t
*this)
258 sqlite3_close(this->db
);
259 this->mutex
->destroy(this->mutex
);
266 sqlite_database_t
*sqlite_database_create(char *uri
)
269 private_sqlite_database_t
*this;
272 * parse sqlite:///path/to/file.db uri
274 if (!strneq(uri
, "sqlite://", 9))
280 this = malloc_thing(private_sqlite_database_t
);
282 this->public.db
.query
= (enumerator_t
* (*)(database_t
*this, char *sql
, ...))query
;
283 this->public.db
.execute
= (int (*)(database_t
*this, int *rowid
, char *sql
, ...))execute
;
284 this->public.db
.destroy
= (void(*)(database_t
*))destroy
;
286 this->mutex
= mutex_create(MUTEX_DEFAULT
);
288 if (sqlite3_open(file
, &this->db
) != SQLITE_OK
)
290 DBG1("opening SQLite database '%s' failed", file
);
295 return &this->public;