php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #53713
Patch session_sqlite3 revision 2011-08-01 05:13 UTC by crrodriguez at opensuse dot org
Patch bugs-53713-sqlite3-session-win32-plus-test revision 2011-05-02 12:07 UTC by jinmoku at hotmail dot com
revision 2011-05-02 12:03 UTC by jinmoku at hotmail dot com
Patch bugs-53713-sqlite3-session.patch revision 2011-05-02 12:05 UTC by jinmoku at hotmail dot com
revision 2011-04-30 02:04 UTC by jinmoku at hotmail dot com

Patch bugs-53713-sqlite3-session-win32-plus-test for SQLite related Bug #53713

Patch version 2011-05-02 12:07 UTC

Return to Bug #53713 | Download this patch
This patch is obsolete

Obsoleted by patches:

This patch renders other patches obsolete

Obsolete patches:

Patch Revisions: 2011-05-02 12:07 UTC | 2011-05-02 12:03 UTC

Developer: jinmoku@hotmail.com

Line 1 (now 1), was 374 lines, now 1 lines
 Index: ext/sqlite3/tests/sqlite3_session_002.phpt
 ===================================================================
 --- ext/sqlite3/tests/sqlite3_session_002.phpt	(revision 0)
 +++ ext/sqlite3/tests/sqlite3_session_002.phpt	(revision 0)
 @@ -0,0 +1,54 @@
 +--TEST--
 +sqlite3, session destroy test
 +--CREDITS--
 +Mats Lindh <mats at lindh.no>
 +#Testfest php.no
 +--INI--
 +session.save_handler = sqlite3
 +--SKIPIF--
 +if (!extension_loaded("session"))
 +{
 +	die("skip Session module not loaded");
 +}
 +if (!extension_loaded("sqlite3"))
 +{
 +	die("skip sqlite3 module not loaded");
 +}
 +--FILE--
 +<?php
 +/* Description: Tests that sqlite will destroy a session when used as a session handler
 +* Source code: ext/sqlite/sess_sqlite3.c
 +*/
 +ob_start();
 +session_save_path(__DIR__ . "/sessiondb.sdb");
 +
 +// start a session and save a value to it before commiting the session to the database
 +session_start();
 +$_SESSION["test"] = "foo_bar";
 +session_write_close();
 +
 +// remove the session value
 +unset($_SESSION["test"]);
 +var_dump(isset($_SESSION["test"]));
 +
 +// start the session again and destroy it
 +session_start();
 +var_dump($_SESSION["test"]);
 +session_destroy();
 +session_write_close();
 +
 +unset($_SESSION["test"]);
 +
 +// check that the session has been destroyed
 +session_start();
 +var_dump(isset($_SESSION["test"]));
 +ob_end_flush();
 +?>
 +--EXPECTF--
 +bool(false)
 +%unicode|string%(7) "foo_bar"
 +bool(false)
 +--CLEAN--
 +<?php
 +	unlink(__DIR__ . "/sessiondb.sdb")
 +?>
 Index: ext/sqlite3/tests/sqlite3_session_001.phpt
 ===================================================================
 --- ext/sqlite3/tests/sqlite3_session_001.phpt	(revision 0)
 +++ ext/sqlite3/tests/sqlite3_session_001.phpt	(revision 0)
 @@ -0,0 +1,46 @@
 +--TEST--
 +sqlite3, session storage test
 +--CREDITS--
 +Mats Lindh <mats at lindh.no>
 +#Testfest php.no
 +--INI--
 +session.save_handler = sqlite3
 +--SKIPIF--
 +if (!extension_loaded("session"))
 +{
 +	die("skip Session module not loaded");
 +}
 +if (!extension_loaded("sqlite3"))
 +{
 +	die("skip Session module not loaded");
 +}
 +--FILE--
 +<?php
 +/* Description: Tests that sqlite can be used as a session save handler
 +* Source code: ext/sqlite/sess_sqlite3.c
 +*/
 +
 +ob_start();
 +session_save_path(__DIR__ . "/sessiondb.sdb");
 +
 +// create the session and set a session value
 +session_start();
 +$_SESSION["test"] = "foo_bar";
 +
 +// close the session and unset the value
 +session_write_close();
 +unset($_SESSION["test"]);
 +var_dump(isset($_SESSION["test"]));
 +
 +// start the session again and check that we have the proper value
 +session_start();
 +var_dump($_SESSION["test"]);
 +ob_end_flush();
 +?>
 +--EXPECTF--
 +bool(false)
 +%unicode|string%(7) "foo_bar"
 +--CLEAN--
 +<?php
 +	unlink(__DIR__ . "/sessiondb.sdb")
 +?>
 Index: ext/sqlite3/config.w32
 ===================================================================
 --- ext/sqlite3/config.w32	(revision 310704)
 +++ ext/sqlite3/config.w32	(working copy)
 @@ -5,7 +5,7 @@
  
  if (PHP_SQLITE3 != "no") {
  	ADD_FLAG("CFLAGS_SQLITE3", "/D SQLITE_THREADSAFE=" + (PHP_ZTS == "yes" ? "1" : "0") + " /D SQLITE_ENABLE_FTS3=1 /D SQLITE_ENABLE_COLUMN_METADATA=1 /D SQLITE_CORE=1 ");
 -	EXTENSION("sqlite3", "sqlite3.c", null, "/I" + configure_module_dirname + "/libsqlite /I" + configure_module_dirname);
 +	EXTENSION("sqlite3", "sqlite3.c sess_sqlite3.c", null, "/I" + configure_module_dirname + "/libsqlite /I" + configure_module_dirname);
  
  	ADD_SOURCES(configure_module_dirname + "/libsqlite", "sqlite3.c", "sqlite3");
  
 Index: ext/sqlite3/sqlite3.c
 ===================================================================
 --- ext/sqlite3/sqlite3.c	(revision 310704)
 +++ ext/sqlite3/sqlite3.c	(working copy)
 @@ -25,6 +25,9 @@
  #include "php.h"
  #include "php_ini.h"
  #include "ext/standard/info.h"
 +#include "ext/standard/info.h"
 +#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
 +#include "ext/session/php_session.h"
  #include "php_sqlite3.h"
  #include "php_sqlite3_structs.h"
  #include "main/SAPI.h"
 @@ -38,6 +41,12 @@
  ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
  
  static PHP_GINIT_FUNCTION(sqlite3);
 +
 +#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
 +extern ps_module ps_mod_sqlite3;
 +#define ps_sqlite3_ptr &ps_mod_sqlite3
 +#endif
 +
  static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6);
  static void sqlite3_param_dtor(void *data);
  static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
 @@ -2114,6 +2123,10 @@
  	php_sqlite3_result_entry = zend_register_internal_class(&ce TSRMLS_CC);
  
  	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);
 @@ -2165,6 +2178,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);
 +
 +extern 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 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
 + */
 \ No newline at end of file
 see bugs-53713-sqlite3-session.patch
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 10:01:28 2024 UTC