diff --git a/plugin/sqlite/Makefile.am b/plugin/sqlite/Makefile.am
new file mode 100644
index 0000000..8d3851c
--- /dev/null
+++ b/plugin/sqlite/Makefile.am
@@ -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
diff --git a/plugin/sqlite/db-sqlite.c b/plugin/sqlite/db-sqlite.c
new file mode 100644
index 0000000..4c0def7
--- /dev/null
+++ b/plugin/sqlite/db-sqlite.c
@@ -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 .
+ */
+
+#include "db-sqlite.h"
+#include
+
+/**
+ * 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;
+}
diff --git a/plugin/sqlite/db-sqlite.h b/plugin/sqlite/db-sqlite.h
new file mode 100644
index 0000000..2d42bd1
--- /dev/null
+++ b/plugin/sqlite/db-sqlite.h
@@ -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 .
+ */
+
+#ifndef DB_SQLITE_H
+#define DB_SQLITE_H
+
+#include
+#include
+
+#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
\ No newline at end of file
diff --git a/vn/schema/config.db b/vn/schema/config.db
new file mode 100644
index 0000000..30ff4e6
Binary files /dev/null and b/vn/schema/config.db differ