Añadidos archivos de SQLite
This commit is contained in:
parent
d47b62e1aa
commit
34c5b7fb40
|
@ -0,0 +1,21 @@
|
||||||
|
include $(top_srcdir)/Makefile.decl
|
||||||
|
|
||||||
|
sqlite_lib_LTLIBRARIES = libdbsqlite.la
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir) \
|
||||||
|
$(glib_CFLAGS)
|
||||||
|
libdbsqlite_la_LIBADD = \
|
||||||
|
$(glib_LIBS) \
|
||||||
|
$(top_builddir)/db/libdb.la \
|
||||||
|
$(sqlite_LIBS)
|
||||||
|
libdbsqlite_la_LDFLAGS = -avoid-version
|
||||||
|
libdbsqlite_la_SOURCES = \
|
||||||
|
db-sqlite.h \
|
||||||
|
db-sqlite.c
|
||||||
|
|
||||||
|
sqlite_libdir = $(plugin_libdir)/sqlite
|
||||||
|
|
||||||
|
install-data-hook:
|
||||||
|
rm -f $(DESTDIR)$(sqlite_libdir)/libdbsqlite.la
|
||||||
|
rm -f $(DESTDIR)$(sqlite_libdir)/libdbsqlite.a
|
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 - Juan Ferrer Toribio
|
||||||
|
*
|
||||||
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "db-sqlite.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION: db-sqlite
|
||||||
|
* @Short_description: manages a connection to a SQLite database.
|
||||||
|
* @Title: DbSqlite
|
||||||
|
* @See_also: #DbConn
|
||||||
|
*
|
||||||
|
* This class manages a connection to a SQLite database internally. This
|
||||||
|
* is accessed through the #DbConn class to internally connect, query and
|
||||||
|
* disconnect the database.
|
||||||
|
**/
|
||||||
|
G_DEFINE_TYPE (DbSqlite, db_sqlite, DB_TYPE_PLUGIN);
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
|
||||||
|
|
||||||
|
static void db_sqlite_close (DbSqlite * self)
|
||||||
|
{
|
||||||
|
if (self->sqlite)
|
||||||
|
{
|
||||||
|
sqlite3_close (self->sqlite);
|
||||||
|
self->sqlite = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean db_sqlite_open (DbSqlite * self, const gchar * host,
|
||||||
|
const gchar * schema, const gchar * user, const gchar * pass, GError ** err)
|
||||||
|
{
|
||||||
|
db_sqlite_close (self);
|
||||||
|
sqlite3_open (schema, &self->sqlite);
|
||||||
|
|
||||||
|
if (!self->sqlite)
|
||||||
|
{
|
||||||
|
g_set_error (err
|
||||||
|
,DB_CONN_LOG_DOMAIN
|
||||||
|
,DB_CONN_ERROR_OPENING
|
||||||
|
,sqlite3_errmsg (self->sqlite)
|
||||||
|
);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void db_sqlite_set_ssl (DbSqlite * self, const gchar * ca)
|
||||||
|
{
|
||||||
|
g_warning ("DbSqlite: SSL not supported by this plugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
static DbResultSet * db_sqlite_query (DbSqlite * self, const gchar * sql, GError ** err)
|
||||||
|
{
|
||||||
|
gint i, j;
|
||||||
|
gint status;
|
||||||
|
sqlite3_stmt * stmt;
|
||||||
|
GValue def = G_VALUE_INIT;
|
||||||
|
DbResult * result;
|
||||||
|
DbResultSet * set = db_result_set_new ();
|
||||||
|
|
||||||
|
while (sql)
|
||||||
|
{
|
||||||
|
status = sqlite3_prepare_v2 (self->sqlite, sql, -1, &stmt, &sql);
|
||||||
|
|
||||||
|
if (status != SQLITE_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
status = sqlite3_step (stmt);
|
||||||
|
|
||||||
|
if (status != SQLITE_DONE && status != SQLITE_ROW)
|
||||||
|
{
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = g_new (DbResult, 1);
|
||||||
|
result->ncols = sqlite3_column_count (stmt);
|
||||||
|
set->results = g_slist_append (set->results, result);
|
||||||
|
|
||||||
|
// INSERT, DELETE or UPDATE
|
||||||
|
|
||||||
|
if (result->ncols == 0)
|
||||||
|
{
|
||||||
|
result->nrows = sqlite3_changes (self->sqlite);
|
||||||
|
result->column = NULL;
|
||||||
|
result->data = NULL;
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SELECT
|
||||||
|
|
||||||
|
result->nrows = 0;
|
||||||
|
result->column = g_new (DbColumn, result->ncols);
|
||||||
|
result->data = g_ptr_array_new_full (2,
|
||||||
|
(GDestroyNotify) db_row_free);
|
||||||
|
|
||||||
|
GType gtypes[result->ncols];
|
||||||
|
|
||||||
|
for (i = 0; i < result->ncols; i++)
|
||||||
|
{
|
||||||
|
DbColumn * column = &result->column[i];
|
||||||
|
column->info = 0;
|
||||||
|
column->name = g_strdup (sqlite3_column_origin_name (stmt, i));
|
||||||
|
column->alias = g_strdup (sqlite3_column_name (stmt, i));
|
||||||
|
column->table = g_strdup (sqlite3_column_table_name (stmt, i));
|
||||||
|
column->table_alias = g_strdup (column->table);
|
||||||
|
column->schema = g_strdup (sqlite3_column_database_name (stmt, i));
|
||||||
|
|
||||||
|
if (!column->alias)
|
||||||
|
column->alias = g_strdup (column->name);
|
||||||
|
|
||||||
|
switch (sqlite3_column_type (stmt, i))
|
||||||
|
{
|
||||||
|
case SQLITE_INTEGER:
|
||||||
|
gtypes[i] = G_TYPE_INT;
|
||||||
|
break;
|
||||||
|
case SQLITE_FLOAT:
|
||||||
|
gtypes[i] = G_TYPE_DOUBLE;
|
||||||
|
break;
|
||||||
|
case SQLITE_BLOB:
|
||||||
|
gtypes[i] = G_TYPE_BYTES;
|
||||||
|
break;
|
||||||
|
case SQLITE_TEXT:
|
||||||
|
case SQLITE_NULL: // TODO
|
||||||
|
default:
|
||||||
|
gtypes[i] = G_TYPE_STRING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_strcmp0 (column->name, "rowid"))
|
||||||
|
{
|
||||||
|
SqlObject * func = sql_function_new ("last_insert_rowid", NULL);
|
||||||
|
|
||||||
|
g_value_init (&def, SQL_TYPE_FUNCTION);
|
||||||
|
g_value_take_object (&def, g_object_ref_sink (func));
|
||||||
|
|
||||||
|
column->info |= DB_COLUMN_PRI_KEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_value_init (&def, GVN_TYPE_NULL);
|
||||||
|
|
||||||
|
column->spec = gvn_param_spec_new_with_attrs (gtypes[i], FALSE, TRUE, &def);
|
||||||
|
g_value_unset (&def);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; status == SQLITE_ROW; i++)
|
||||||
|
{
|
||||||
|
DbRow * row = db_row_new (result->ncols, i);
|
||||||
|
g_ptr_array_add (result->data, row);
|
||||||
|
|
||||||
|
for (j = 0; j < result->ncols; j++)
|
||||||
|
if (sqlite3_column_type (stmt, j) != SQLITE_NULL)
|
||||||
|
{
|
||||||
|
GValue * value = &row->value[j];
|
||||||
|
g_value_init (value, gtypes[j]);
|
||||||
|
|
||||||
|
switch (gtypes[j])
|
||||||
|
{
|
||||||
|
case G_TYPE_INT:
|
||||||
|
g_value_set_int (value, sqlite3_column_int (stmt, j));
|
||||||
|
break;
|
||||||
|
case G_TYPE_DOUBLE:
|
||||||
|
g_value_set_double (value, sqlite3_column_double (stmt, j));
|
||||||
|
break;
|
||||||
|
case G_TYPE_STRING:
|
||||||
|
g_value_set_string (value, (gchar *) sqlite3_column_text (stmt, j));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (gtypes[i] == G_TYPE_BYTES)
|
||||||
|
{
|
||||||
|
int len = sqlite3_column_bytes (stmt, j);
|
||||||
|
const void * blob = sqlite3_column_blob (stmt, j);
|
||||||
|
g_value_take_boxed (value, g_bytes_new (blob, len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_value_init (&row->value[j], GVN_TYPE_NULL);
|
||||||
|
|
||||||
|
status = sqlite3_step (stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
result->nrows = i;
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_errcode (self->sqlite) != SQLITE_OK)
|
||||||
|
{
|
||||||
|
db_result_set_free (set);
|
||||||
|
set = NULL;
|
||||||
|
|
||||||
|
g_set_error (err
|
||||||
|
,DB_CONN_LOG_DOMAIN
|
||||||
|
,DB_CONN_ERROR_UNKNOW
|
||||||
|
,sqlite3_errmsg (self->sqlite)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void db_sqlite_kill_query (DbSqlite * self)
|
||||||
|
{
|
||||||
|
g_warning ("DbSqlite: Kill doesn't supported by this plugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void db_sqlite_value_render (SqlValue * self, SqlRender * render, SqlBatch * batch)
|
||||||
|
{
|
||||||
|
if (G_VALUE_TYPE (self->value) == G_TYPE_BYTES)
|
||||||
|
{
|
||||||
|
// TODO: Render binary data
|
||||||
|
g_warning ("DbSqlite: Can't render binary data");
|
||||||
|
sql_render_set_error (render);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sql_object_render (SQL_OBJECT (self), render, batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
|
||||||
|
|
||||||
|
static void db_sqlite_init (DbSqlite * self)
|
||||||
|
{
|
||||||
|
SqlRender * render = sql_render_new ('`');
|
||||||
|
sql_render_register_function (render, SQL_TYPE_VALUE,
|
||||||
|
(SqlRenderFunc) db_sqlite_value_render);
|
||||||
|
|
||||||
|
DB_PLUGIN (self)->render = render;
|
||||||
|
self->sqlite = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void db_sqlite_class_init (DbSqliteClass * k)
|
||||||
|
{
|
||||||
|
DbPluginClass * klass = DB_PLUGIN_CLASS (k);
|
||||||
|
klass->open = (DbPluginOpenFunc) db_sqlite_open;
|
||||||
|
klass->close = (DbPluginCloseFunc) db_sqlite_close;
|
||||||
|
klass->set_ssl = (DbPluginSetSSL) db_sqlite_set_ssl;
|
||||||
|
klass->query = (DbPluginQueryFunc) db_sqlite_query;
|
||||||
|
klass->kill_query = (DbPluginKillQueryFunc) db_sqlite_kill_query;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 - Juan Ferrer Toribio
|
||||||
|
*
|
||||||
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DB_SQLITE_H
|
||||||
|
#define DB_SQLITE_H
|
||||||
|
|
||||||
|
#include <db/db.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
#define DB_TYPE_SQLITE (db_sqlite_get_type ())
|
||||||
|
#define DB_SQLITE(self) (G_TYPE_CHECK_INSTANCE_CAST ((self), DB_TYPE_SQLITE, DbSqlite))
|
||||||
|
#define DB_IS_SQLITE(self) (G_TYPE_CHECK_INSTANCE_TYPE ((self), DB_TYPE_SQLITE))
|
||||||
|
#define DB_SQLITE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DB_TYPE_SQLITE, DbSqliteClass))
|
||||||
|
#define DB_IS_SQLITE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DB_TYPE_SQLITE))
|
||||||
|
#define DB_SQLITE_GET_CLASS(self) (G_TYPE_INSTANCE_GET_CLASS ((self), DB_TYPE_SQLITE, DbSqliteClass))
|
||||||
|
|
||||||
|
typedef struct _DbSqlite DbSqlite;
|
||||||
|
typedef struct _DbSqliteClass DbSqliteClass;
|
||||||
|
|
||||||
|
struct _DbSqlite
|
||||||
|
{
|
||||||
|
DbPlugin parent;
|
||||||
|
sqlite3 * sqlite;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _DbSqliteClass
|
||||||
|
{
|
||||||
|
DbPluginClass parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType db_sqlite_get_type ();
|
||||||
|
DbConn * db_sqlite_new ();
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
Reference in New Issue