Patch bugs-53713-sqlite3-session.patch for SQLite related Bug #53713
Patch version 2011-04-30 02:04 UTC
Return to Bug #53713 |
Download this patch
Patch Revisions:
Developer: jinmoku@hotmail.com
Index: ext/sqlite3/sqlite3.c
===================================================================
--- ext/sqlite3/sqlite3.c (revision 310655)
+++ ext/sqlite3/sqlite3.c (working copy)
@@ -25,6 +25,9 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
+#include "ext/session/php_session.h"
+#endif
#include "php_sqlite3.h"
#include "php_sqlite3_structs.h"
#include "main/SAPI.h"
@@ -2115,6 +2118,10 @@
REGISTER_INI_ENTRIES();
+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
+ php_session_register_module(ps_sqlite3_ptr);
+#endif
+
REGISTER_LONG_CONSTANT("SQLITE3_ASSOC", PHP_SQLITE3_ASSOC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLITE3_NUM", PHP_SQLITE3_NUM, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SQLITE3_BOTH", PHP_SQLITE3_BOTH, CONST_CS | CONST_PERSISTENT);
@@ -2165,6 +2172,16 @@
}
/* }}} */
+/* {{{ sqlite3_module_dep
+*/
+static const zend_module_dep sqlite3_deps[] = {
+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
+ ZEND_MOD_REQUIRED("session")
+#endif
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
/* {{{ sqlite3_module_entry
*/
zend_module_entry sqlite3_module_entry = {
Index: ext/sqlite3/sess_sqlite3.c
===================================================================
--- ext/sqlite3/sess_sqlite3.c (revision 0)
+++ ext/sqlite3/sess_sqlite3.c (revision 0)
@@ -0,0 +1,190 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2011 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: John Coggeshall <john@php.net> |
+ | Wez Furlong <wez@thebrainroom.com> |
+ | Stealth35 <jinmoku@hotmail.com> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+
+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
+
+#include "ext/session/php_session.h"
+#include "ext/standard/php_lcg.h"
+#include <sqlite3.h>
+#define SQLITE_RETVAL(__r) ((__r) == SQLITE_OK ? SUCCESS : FAILURE)
+#define PS_SQLITE_DATA sqlite3 *db = (sqlite3*)PS_GET_MOD_DATA()
+
+PS_FUNCS(sqlite3);
+
+ps_module ps_mod_sqlite3 = {
+ PS_MOD(sqlite3)
+};
+
+PS_OPEN_FUNC(sqlite3)
+{
+ int rc;
+ sqlite3 *db;
+
+ /* TODO: do we need a safe_mode check here? */
+ rc = sqlite3_open(save_path, &db);
+ if (rc) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "SQLite: failed to open/create session database `%s' - %s", save_path, sqlite3_errmsg(db));
+ return FAILURE;
+ }
+
+ /* allow up to 1 minute when busy */
+ sqlite3_busy_timeout(db, 60000);
+
+ sqlite3_exec(db, "PRAGMA default_synchronous = OFF", NULL, NULL, NULL);
+ sqlite3_exec(db, "PRAGMA count_changes = OFF", NULL, NULL, NULL);
+
+ /* This will fail if the table already exists, but that's not a big problem. I'm
+ unclear as to how to check for a table's existence in SQLite -- that would be better here. */
+ sqlite3_exec(db,
+ "CREATE TABLE session_data ("
+ " sess_id PRIMARY KEY,"
+ " value TEXT, "
+ " updated INTEGER "
+ ")", NULL, NULL, NULL);
+
+ PS_SET_MOD_DATA(db);
+
+ return SUCCESS;
+}
+
+PS_CLOSE_FUNC(sqlite3)
+{
+ PS_SQLITE_DATA;
+
+ sqlite3_close(db);
+
+ return SUCCESS;
+}
+
+PS_READ_FUNC(sqlite3)
+{
+ PS_SQLITE_DATA;
+ char *query;
+ const char *tail;
+ sqlite3_stmt *stmt;
+ int bytes, result;
+ const char *rowdata;
+
+ *val = NULL;
+
+ query = sqlite3_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
+ if (query == NULL) {
+ /* no memory */
+ return FAILURE;
+ }
+
+ if (sqlite3_prepare(db, query, strlen(query) + 1, &stmt, &tail) != SQLITE_OK) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session read query: %s", sqlite3_errmsg(db));
+ sqlite3_free(query);
+ return FAILURE;
+ }
+
+ result = sqlite3_step(stmt);
+ if(result == SQLITE_ROW) {
+ *vallen = sqlite3_column_bytes(stmt, 0);
+ rowdata = sqlite3_column_text(stmt, 0);
+ if (*vallen) {
+ *val = emalloc(*vallen);
+ memcpy(*val, rowdata, *vallen);
+ (*val)[*vallen] = '\0';
+ } else {
+ *val = STR_EMPTY_ALLOC();
+ }
+ }
+
+ if (SQLITE_OK != sqlite3_finalize(stmt)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session read: error %s", sqlite3_errmsg(db));
+ }
+
+ sqlite3_free(query);
+
+ return *val == NULL ? FAILURE : SUCCESS;
+}
+
+PS_WRITE_FUNC(sqlite3)
+{
+ PS_SQLITE_DATA;
+ char *error;
+ char *query;
+ time_t t;
+ int rv;
+
+ t = time(NULL);
+
+ query = sqlite3_mprintf("REPLACE INTO session_data VALUES('%q', '%q', %d)", key, val, t);
+ rv = sqlite3_exec(db, query, NULL, NULL, &error);
+ if (rv != SQLITE_OK) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session write query failed: %s", error);
+ sqlite3_free(error);
+ }
+ sqlite3_free(query);
+
+ return SQLITE_RETVAL(rv);
+}
+
+PS_DESTROY_FUNC(sqlite3)
+{
+ char *query;
+ int rv;
+ PS_SQLITE_DATA;
+
+ query = sqlite3_mprintf("DELETE FROM session_data WHERE sess_id='%q'", key);
+ rv = sqlite3_exec(db, query, NULL, NULL, NULL);
+ sqlite3_free(query);
+
+ return SQLITE_RETVAL(rv);
+}
+
+PS_GC_FUNC(sqlite3)
+{
+ PS_SQLITE_DATA;
+ char *query;
+ int rv;
+ time_t t = time(NULL);
+
+ query = sqlite3_mprintf("DELETE FROM session_data WHERE (%d - updated) > %d", t, maxlifetime);
+ rv = sqlite3_exec(db, query, NULL, NULL, NULL);
+ sqlite3_free(query);
+
+ /* because SQLite does not actually clear the deleted data from the database
+ * we need to occassionaly do so manually to prevent the sessions database
+ * from growing endlessly.
+ */
+ if ((int) ((float) PS(gc_divisor) * PS(gc_divisor) * php_combined_lcg(TSRMLS_C)) < PS(gc_probability)) {
+ rv = sqlite3_exec(db, "VACUUM", NULL, NULL, NULL);
+ }
+ return SQLITE_RETVAL(rv);
+}
+
+#endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
Index: ext/sqlite3/config0.m4
===================================================================
--- ext/sqlite3/config0.m4 (revision 310655)
+++ ext/sqlite3/config0.m4 (working copy)
@@ -85,7 +85,7 @@
AC_DEFINE(HAVE_SQLITE3,1,[ ])
- sqlite3_sources="sqlite3.c $sqlite3_extra_sources"
+ sqlite3_sources="sqlite3.c sess_sqlite3.c $sqlite3_extra_sources"
PHP_NEW_EXTENSION(sqlite3, $sqlite3_sources, $ext_shared,,$PHP_SQLITE3_CFLAGS)
PHP_ADD_BUILD_DIR([$ext_builddir/libsqlite])
|