summaryrefslogtreecommitdiffstats
path: root/clib/src/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'clib/src/db.c')
-rw-r--r--clib/src/db.c400
1 files changed, 400 insertions, 0 deletions
diff --git a/clib/src/db.c b/clib/src/db.c
new file mode 100644
index 0000000..e61726c
--- /dev/null
+++ b/clib/src/db.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * File: db.c
+ * Author: Shaun Wetzstein <shaun@us.ibm.com>
+ * Descr: SQlite wrapper
+ * Note:
+ * Date: 02/25/11
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sqlite3.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "assert.h"
+#include "err.h"
+
+#include "db.h"
+
+/* =======================================================================*/
+
+int db_init(db_t * self, const char *path)
+{
+ assert(self != NULL);
+
+ self->path = strdup(path);
+ if (self->path == NULL) {
+ ERRNO(errno);
+ return -1;
+ }
+
+ self->db = NULL;
+
+ return 0;
+}
+
+int db_delete(db_t * self)
+{
+ if (self != NULL) {
+ db_close(self);
+ if (self->path != NULL)
+ free((char *)self->path);
+ memset(self, 0, sizeof(*self));
+ }
+
+ return 0;
+}
+
+int db_execute(db_t * self, const char *fmt, ...)
+{
+ assert(self != NULL);
+
+ va_list ap;
+ va_start(ap, fmt);
+ char *sql = NULL;
+ vasprintf(&sql, fmt, ap);
+
+ assert(sql != NULL);
+
+ int rc = sqlite3_exec(self->db, sql, NULL, NULL, NULL);
+ if (sql != NULL)
+ free(sql);
+
+ if (rc != DB_OK) {
+ DBERR(self->db);
+ return -1;
+ }
+
+ return 0;
+}
+
+int db_open(db_t * self, int flags)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->db != NULL)
+ db_close(self);
+
+ rc = sqlite3_open_v2(self->path, &self->db, flags, NULL);
+ if (rc != DB_OK) {
+ DBERR(self->db);
+ return -1;
+ }
+
+ return rc;
+}
+
+int db_close(db_t * self)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->db != NULL) {
+ /* finalize statements */
+ rc = sqlite3_close(self->db);
+ }
+
+ return rc;
+}
+
+int db_register_function(db_t * self, const char *name, int argc, db_f func,
+ void *data)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ rc = sqlite3_create_function(self->db, name, argc, SQLITE_ANY, data,
+ func, NULL, NULL);
+ if (rc != 0) {
+ DBERR(self->db);
+ return -1;
+ }
+
+ return rc;
+}
+
+int db_begin(db_t * self, transaction_type_t type)
+{
+ assert(self != NULL);
+
+ const char *tran_type = NULL;
+
+ switch (type) {
+ case tt_DEFERRED:
+ tran_type = "DEFERRED";
+ break;
+ case tt_IMMEDIATE:
+ tran_type = "IMMEDIATE";
+ break;
+ case tt_EXCLUSIVE:
+ tran_type = "EXCLUSIVE";
+ break;
+ default:
+ UNEXPECTED("'%d' invalid transaction type", type);
+ return -1;
+ }
+
+ return db_execute(self, "BEGIN %s TRANSACTION", tran_type);
+}
+
+int db_commit(db_t * self)
+{
+ assert(self != NULL);
+ return db_execute(self, "COMMIT TRANSACTION");
+}
+
+int db_rollback(db_t * self)
+{
+ assert(self != NULL);
+ return db_execute(self, "ROLLBACK TRANSACTION");
+}
+
+/* =======================================================================*/
+
+int statement_init(statement_t * self, db_t * db)
+{
+ assert(self != NULL);
+ assert(db != NULL);
+
+ self->db = db;
+ self->stmt = NULL;
+
+ return 0;
+}
+
+int statement_delete(statement_t * self)
+{
+ assert(self != NULL);
+
+ if (self->stmt != NULL) {
+ statement_finalize(self);
+ self->stmt = NULL;
+ }
+
+ self->db = NULL;
+ free(self);
+
+ return 0;
+}
+
+int statement_prepare(statement_t * self, const char *sql)
+{
+ assert(self != NULL);
+ assert(sql != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_finalize(self->stmt);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ rc = sqlite3_prepare_v2(self->db->db, sql, -1, &self->stmt, NULL);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+
+ return rc;
+}
+
+int statement_step(statement_t * self)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_step(self->stmt);
+
+ switch (rc) {
+ case DB_DONE:
+ case DB_ROW:
+ break;
+ default:
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
+int statement_reset(statement_t * self)
+{
+ self = NULL;
+ return 0;
+}
+
+int statement_finalize(statement_t * self)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_finalize(self->stmt);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ self->stmt = NULL;
+ }
+
+ return rc;
+}
+
+int statement_bind_int(statement_t * self, int pos, int val)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_bind_int(self->stmt, pos, val);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
+int statement_bind_int64(statement_t * self, int pos, int64_t val)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_bind_int64(self->stmt, pos, val);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
+int statement_bind_text(statement_t * self, int pos, const char *val)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_bind_text(self->stmt, pos, val, -1,
+ SQLITE_TRANSIENT);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
+int statement_bind_blob(statement_t * self, int pos, const void *val, int size)
+{
+ assert(self != NULL);
+
+ int rc = DB_OK;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_bind_blob(self->stmt, pos, val, size,
+ SQLITE_TRANSIENT);
+ if (rc != DB_OK) {
+ SQLERR(self->db->db, self->stmt);
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
+int statement_column_int(statement_t * self, int pos)
+{
+ assert(self != NULL);
+ return sqlite3_column_int(self->stmt, pos);
+}
+
+int64_t statement_column_int64(statement_t * self, int pos)
+{
+ assert(self != NULL);
+ return sqlite3_column_int64(self->stmt, pos);
+}
+
+int statement_column_bytes(statement_t * self, int pos)
+{
+ assert(self != NULL);
+ return sqlite3_column_bytes(self->stmt, pos);
+}
+
+const unsigned char *statement_column_text(statement_t * self, int pos)
+{
+ assert(self != NULL);
+
+ const unsigned char *rc = NULL;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_column_text(self->stmt, pos);
+ if (rc == NULL) {
+ SQLERR(self->db->db, self->stmt);
+ return NULL;
+ }
+ }
+
+ return rc;
+}
+
+const void *statement_column_blob(statement_t * self, int pos)
+{
+ assert(self != NULL);
+
+ const void *rc = NULL;
+
+ if (self->stmt != NULL) {
+ rc = sqlite3_column_blob(self->stmt, pos);
+ if (rc == NULL) {
+ SQLERR(self->db->db, self->stmt);
+ return NULL;
+ }
+ }
+
+ return rc;
+}
+
+/* =======================================================================*/
OpenPOWER on IntegriCloud