From 3b63c88c3fa0e9331f6e2a37782481bbfce9a9df Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Mon, 29 Oct 2012 21:16:33 +0100 Subject: [PATCH] Added the PDO pseudo-engine --- Makefile | 1 + src/database/Makefile | 17 +++- src/database/pdo.c | 197 ++++++++++++++++++++++++++++++++++++++ src/database/project.conf | 10 +- 4 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 src/database/pdo.c diff --git a/Makefile b/Makefile index ea9847b..24dfa84 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ dist: $(PACKAGE)-$(VERSION)/src/database.c \ $(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/project.conf \ + $(PACKAGE)-$(VERSION)/src/database/pdo.c \ $(PACKAGE)-$(VERSION)/src/database/pgsql.c \ $(PACKAGE)-$(VERSION)/src/database/sqlite2.c \ $(PACKAGE)-$(VERSION)/src/database/sqlite3.c \ diff --git a/src/database/Makefile b/src/database/Makefile index 0d2fd1d..316870e 100644 --- a/src/database/Makefile +++ b/src/database/Makefile @@ -1,4 +1,4 @@ -TARGETS = pgsql.so sqlite2.so sqlite3.so template.so +TARGETS = pdo.so pgsql.so sqlite2.so sqlite3.so template.so PREFIX = /usr/local DESTDIR = LIBDIR = $(PREFIX)/lib @@ -18,6 +18,13 @@ INSTALL ?= install all: $(TARGETS) +pdo_OBJS = pdo.o +pdo_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +pdo_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +pdo.so: $(pdo_OBJS) + $(CCSHARED) -o pdo.so $(pdo_OBJS) $(pdo_LDFLAGS) + pgsql_OBJS = pgsql.o pgsql_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) -I `pg_config --includedir` $(CFLAGSF) $(CFLAGS) pgsql_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) -L `pg_config --libdir` -Wl,-rpath,`pg_config --libdir` `pg_config --libs` -lpq @@ -46,6 +53,9 @@ template_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) template.so: $(template_OBJS) $(CCSHARED) -o template.so $(template_OBJS) $(template_LDFLAGS) +pdo.o: pdo.c database.h ../../config.h + $(CC) $(pdo_CFLAGS) -c pdo.c + pgsql.o: pgsql.c database.h $(CC) $(pgsql_CFLAGS) -c pgsql.c @@ -59,12 +69,14 @@ template.o: template.c database.h $(CC) $(template_CFLAGS) -c template.c clean: - $(RM) -- $(pgsql_OBJS) $(sqlite2_OBJS) $(sqlite3_OBJS) $(template_OBJS) + $(RM) -- $(pdo_OBJS) $(pgsql_OBJS) $(sqlite2_OBJS) $(sqlite3_OBJS) $(template_OBJS) distclean: clean $(RM) -- $(TARGETS) install: $(TARGETS) + $(MKDIR) $(DESTDIR)$(LIBDIR)/Database/engine + $(INSTALL) -m 0644 -- pdo.so $(DESTDIR)$(LIBDIR)/Database/engine/pdo.so $(MKDIR) $(DESTDIR)$(LIBDIR)/Database/engine $(INSTALL) -m 0644 -- pgsql.so $(DESTDIR)$(LIBDIR)/Database/engine/pgsql.so $(MKDIR) $(DESTDIR)$(LIBDIR)/Database/engine @@ -73,6 +85,7 @@ install: $(TARGETS) $(INSTALL) -m 0644 -- sqlite3.so $(DESTDIR)$(LIBDIR)/Database/engine/sqlite3.so uninstall: + $(RM) -- $(DESTDIR)$(LIBDIR)/Database/engine/pdo.so $(RM) -- $(DESTDIR)$(LIBDIR)/Database/engine/pgsql.so $(RM) -- $(DESTDIR)$(LIBDIR)/Database/engine/sqlite2.so $(RM) -- $(DESTDIR)$(LIBDIR)/Database/engine/sqlite3.so diff --git a/src/database/pdo.c b/src/database/pdo.c new file mode 100644 index 0000000..5c9bace --- /dev/null +++ b/src/database/pdo.c @@ -0,0 +1,197 @@ +/* $Id$ */ +/* Copyright (c) 2012 Pierre Pronchery */ +/* This file is part of DeforaOS Database libDatabase */ +/* 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, version 3 of the License. + * + * 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 +#include +#ifdef DEBUG +# include +#endif +#include +#include +#include "database.h" +#include "../../config.h" + +#ifndef PREFIX +# define PREFIX "/usr/local" +#endif +#ifndef LIBDIR +# define LIBDIR PREFIX "/lib" +#endif + + +/* PDO */ +/* private */ +/* types */ +typedef struct _DatabasePlugin +{ + Plugin * plugin; + DatabasePluginDefinition * dplugin; + DatabasePlugin * database; +} PDO; + +typedef struct _DatabaseStatement +{ + DatabaseStatement * statement; +} PDOStatement; + + +/* protected */ +/* prototypes */ +/* plug-in */ +static PDO * _pdo_init(Config * config, char const * section); +static void _pdo_destroy(PDO * pdo); + +static int _pdo_get_last_id(PDO * pdo); + +static int _pdo_query(PDO * pdo, char const * query, DatabaseCallback callback, + void * data); + +static PDOStatement * _pdo_prepare_new(PDO * pdo, char const * query); +static void _pdo_prepare_delete(PDO * pdo, PDOStatement * statement); +static int _pdo_prepare_query(PDO * pdo, PDOStatement * statement, + DatabaseCallback callback, void * data, va_list args); + + +/* public */ +/* variables */ +DatabasePluginDefinition database = +{ + "PDO", + NULL, + _pdo_init, + _pdo_destroy, + _pdo_get_last_id, + _pdo_query, + _pdo_prepare_new, + _pdo_prepare_delete, + _pdo_prepare_query +}; + + +/* private */ +/* functions */ +/* _pdo_init */ +static PDO * _pdo_init(Config * config, char const * section) +{ + PDO * pdo; + char const * dsn; + char const sqlite3[] = "sqlite:"; + char const * backend = NULL; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, section); +#endif + if((dsn = config_get(config, section, "dsn")) == NULL + || (config = config_new()) == NULL) + return NULL; + /* FIXME implement more backends */ + if(strncmp(dsn, sqlite3, sizeof(sqlite3) - 1) == 0) + { + backend = "sqlite3"; + section = "database::sqlite3"; + /* XXX may fail */ + config_set(config, section, "filename", + &dsn[sizeof(sqlite3) - 1]); + } + else + /* XXX report error */ + return NULL; + if((pdo = object_new(sizeof(*pdo))) == NULL) + { + config_delete(config); + return NULL; + } + pdo->database = NULL; + if((pdo->plugin = plugin_new(LIBDIR, PACKAGE, "database", backend)) + == NULL + || (pdo->dplugin = plugin_lookup(pdo->plugin, + "database")) == NULL + || (pdo->database = pdo->dplugin->init(config, section)) + == NULL) + { + config_delete(config); + _pdo_destroy(pdo); + return NULL; + } + config_delete(config); + return pdo; +} + + +/* _pdo_destroy */ +static void _pdo_destroy(PDO * pdo) +{ + if(pdo->database != NULL) + pdo->dplugin->destroy(pdo->database); + if(pdo->plugin != NULL) + plugin_delete(pdo->plugin); + object_delete(pdo); +} + + +/* accessors */ +/* _pdo_get_last_id */ +static int _pdo_get_last_id(PDO * pdo) +{ + return pdo->dplugin->get_last_id(pdo->database); +} + + +/* useful */ +/* _pdo_prepare_new */ +static PDOStatement * _pdo_prepare_new(PDO * pdo, char const * query) +{ + PDOStatement * statement; + + if((statement = object_new(sizeof(*statement))) == NULL) + return NULL; + if((statement->statement = pdo->dplugin->prepare_new(pdo->database, + query)) == NULL) + { + object_delete(statement); + return NULL; + } + return statement; +} + + +/* _pdo_prepare_delete */ +static void _pdo_prepare_delete(PDO * pdo, PDOStatement * statement) +{ + pdo->dplugin->prepare_delete(pdo->database, statement->statement); + object_delete(statement); +} + + +/* _pdo_prepare_query */ +static int _pdo_prepare_query(PDO * pdo, PDOStatement * statement, + DatabaseCallback callback, void * data, va_list args) +{ + return pdo->dplugin->prepare_query(pdo->database, statement->statement, + callback, data, args); +} + + +/* _pdo_query */ +static int _pdo_query(PDO * pdo, char const * query, DatabaseCallback callback, + void * data) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, query); +#endif + return pdo->dplugin->query(pdo->database, query, callback, data); +} diff --git a/src/database/project.conf b/src/database/project.conf index 1539292..af50192 100644 --- a/src/database/project.conf +++ b/src/database/project.conf @@ -1,8 +1,16 @@ -targets=pgsql,sqlite2,sqlite3,template +targets=pdo,pgsql,sqlite2,sqlite3,template cflags_force=-W -fPIC cflags=-Wall -g -O2 -pedantic dist=Makefile,database.h +[pdo] +type=plugin +sources=pdo.c +install=$(LIBDIR)/Database/engine + +[pdo.c] +depends=database.h,../../config.h + [pgsql] type=plugin cppflags=-I `pg_config --includedir`