tagged 1.8 and released

git-svn-id: https://plugins.svn.wordpress.org/sqlite-integration/tags/1.8@1106368 b8457f37-d9ea-0310-8a92-e5e31aec5664
This commit is contained in:
kjmtsh 2015-03-05 21:01:35 +00:00
parent 8286b0ac20
commit d45bbaaa2f
20 changed files with 6121 additions and 5888 deletions

8
BUGS Normal file
View File

@ -0,0 +1,8 @@
* Version 1.7 can't create wp-config.php when installing with WordPress 4.0
When install process notices that there's no wp-config.php, it tries to
create one from wp-config-sample.php. During that time, WordPress unsets
global $wpdb and calls require_wp_db() function.
That function newly instantiates wpdb class. SQLite Integration has no
way of intercepting that process.

49
ChangeLog Normal file
View File

@ -0,0 +1,49 @@
2015-03-06 KOJIMA Toshiyasu
* version 1.8 release.
* readme.txt, readme-ja.txt: updated.
* query_create.class.php: fixed the index query regexp.
* query.class.php: added 'orderby_callback' method.
This is a workaround for PHP 5.2.x compatibility issue.
2015-03-05 KOJIMA Toshiyasu
* pdodb.class.php: removed the unnecessary require directive.
* pdoengin.class.php: revised install process algorithm.
Database directory and file check was too late.
Changed the database directory permission.
2014-10-01 KOJIMA Toshiyasu
* pdoengine.class.php: revised pdoengine class constructor definition
in order to reuse the PDO instance.
* pdodb.class.php, pdoengine.class.php: moved the foreign key check
from PDODB class to PDOEngine class init() method.
* functions.php, functions-5-2.php: check if PDO instance is not null
to avoid displaying Zend debugger/Xdebug messages. If null, constructor
executes wp_die() function.
* query_create.class.php: changed the data type rewriting method.
When a field name is the same as data type, e.g. "date" or "timestamp",
add a single quote to the field name and avoid to be rewritten.
This works only if the field name is on the top of the line, according
to the rule of dbDelta() function.
Added the new function to quote illegal field name, e.g. "default" or
"values", for SQLite. This is for the plugins that use those names to
create tables without errors.
2014-09-05 KOJIMA Toshiyasu
* version 1.7 release.
* update readme.txt and readme-ja.txt.
2014-08-29 KOJIMA Toshiyasu
* Added ChangeLog and BUGS files.

3
db.php
View File

@ -5,7 +5,7 @@
* This file must be placed in the directory wordpress/wp-content/db.php.
* WordPress loads this file automatically.
*
* @version 1.6.2
* @version 1.8
* @package SQLite Integration
* @author Kojima Toshiyasu
*
@ -34,7 +34,6 @@ if (!defined('ABSPATH')) { // Oh, you are not WordPress!
if (defined('USE_MYSQL') && USE_MYSQL) return;
function pdo_log_error($message, $data = null) {
if (strpos($_SERVER['SCRIPT_NAME'], 'wp-admin') !== false) {
$admin_dir = '';
} else {

View File

@ -34,6 +34,9 @@ class PDOSQLiteUDFS {
* @param reference to PDO object $pdo
*/
public function __construct(&$pdo){
if (!$pdo) {
wp_die('Database is not initialized.', 'Database Error');
}
foreach ($this->functions as $f=>$t) {
$pdo->sqliteCreateFunction($f, array($this, $t));
}
@ -172,7 +175,6 @@ class PDOSQLiteUDFS {
//convert to ISO time
$date = date("Y-m-d H:i:s", $field);
//now submit to dateformat
return is_null($format) ? $date : $self->dateformat($date, $format);
}
/**
@ -342,7 +344,6 @@ class PDOSQLiteUDFS {
$type .= 's';
}
return "$_parts[0] $_parts[1]";
break;
case "minute_second":
list($minutes, $seconds) = explode (':', $_parts[0]);
$minutes = intval($minutes);
@ -350,8 +351,6 @@ class PDOSQLiteUDFS {
$minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute";
$seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second";
return "$minutes $seconds";
break;
case "hour_second":
list($hours, $minutes, $seconds) = explode (':', $_parts[0]);
$hours = intval($hours);
@ -361,7 +360,6 @@ class PDOSQLiteUDFS {
$minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute";
$seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second";
return "$hours $minutes $seconds";
break;
case "hour_minute":
list($hours, $minutes) = explode (':', $_parts[0]);
$hours = intval($hours);
@ -369,7 +367,6 @@ class PDOSQLiteUDFS {
$hours = ($hours > 1) ? "$hours hours" : "$hours hour";
$minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute";
return "$hours $minutes";
break;
case "day_second":
$days = intval($_parts[0]);
list($hours, $minutes, $seconds) = explode (':', $_parts[1]);
@ -381,7 +378,6 @@ class PDOSQLiteUDFS {
$minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute";
$seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second";
return "$days $hours $minutes $seconds";
break;
case "day_minute":
$days = intval($_parts[0]);
list($hours, $minutes) = explode (':', $_parts[1]);
@ -391,14 +387,12 @@ class PDOSQLiteUDFS {
$hours = ($hours > 1) ? "$hours hours" : "$hours hour";
$minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute";
return "$days $hours $minutes";
break;
case "day_hour":
$days = intval($_parts[0]);
$hours = intval($_parts[1]);
$days = $days > 1 ? "$days days" : "$days day";
$hours = ($hours > 1) ? "$hours hours" : "$hours hour";
return "$days $hours";
break;
case "year_month":
list($years, $months) = explode ('-', $_parts[0]);
$years = intval($years);
@ -406,7 +400,6 @@ class PDOSQLiteUDFS {
$years = ($years > 1) ? "$years years" : "$years year";
$months = ($months > 1) ? "$months months": "$months month";
return "$years $months";
break;
default:
return false;
}
@ -488,14 +481,21 @@ class PDOSQLiteUDFS {
* @return unsigned integer
*/
public function field() {
global $wpdb;
$numArgs = func_num_args();
if ($numArgs < 2 or is_null(func_get_arg(0))) {
return 0;
} else {
$arg_list = func_get_args();
}
$arr = func_get_args();
$searchString = strtolower(array_shift($arr));
$searchString = array_shift($arg_list);
$str_to_check = substr($searchString, 0, strpos($searchString, '.'));
$str_to_check = str_replace($wpdb->prefix, '', $str_to_check);
if ($str_to_check && in_array(trim($str_to_check), $wpdb->tables)) return;
for ($i = 0; $i < $numArgs-1; $i++) {
if ($searchString === strtolower($arr[$i])) return $i + 1;
if ($searchString === strtolower($arg_list[$i])) {
return $i + 1;
}
}
return 0;
}
@ -707,8 +707,8 @@ class PDOSQLiteUDFS {
* @return string representing the version number: major_version.minor_version
*/
public function version() {
// global $required_mysql_version;
// return $required_mysql_version;
//global $required_mysql_version;
//return $required_mysql_version;
return '5.5';
}
}

View File

@ -34,6 +34,9 @@ class PDOSQLiteUDFS {
* @param reference to PDO object $pdo
*/
public function __construct(&$pdo){
if (!$pdo) {
wp_die('Database is not initialized.', 'Database Error');
}
foreach ($this->functions as $f=>$t) {
$pdo->sqliteCreateFunction($f, array($this, $t));
}
@ -342,34 +345,27 @@ class PDOSQLiteUDFS {
case "minute_second":
list($minutes, $seconds) = explode(':', $_parts[0]);
return 'PT' . $minutes . 'M' . $seconds . 'S';
break;
case "hour_second":
list($hours, $minutes, $seconds) = explode (':', $_parts[0]);
return 'PT' . $hours . 'H' . $minutes . 'M' . $seconds . 'S';
break;
case "hour_minute":
list($hours, $minutes) = explode (':', $_parts[0]);
return 'PT' . $hours . 'H' . $minutes . 'M';
break;
case "day_second":
$days = intval($_parts[0]);
list($hours, $minutes, $seconds) = explode (':', $_parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M' . $seconds . 'S';
break;
case "day_minute":
$days = intval($_parts[0]);
list($hours, $minutes) = explode(':', $parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M';
break;
case "day_hour":
$days = intval($_parts[0]);
$hours = intval($_parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H';
break;
case "year_month":
list($years, $months) = explode ('-', $_parts[0]);
return 'P' . $years . 'Y' . $months . 'M';
break;
}
}
/**
@ -449,6 +445,7 @@ class PDOSQLiteUDFS {
* @return unsigned integer
*/
public function field() {
global $wpdb;
$numArgs = func_num_args();
if ($numArgs < 2 or is_null(func_get_arg(0))) {
return 0;
@ -456,6 +453,9 @@ class PDOSQLiteUDFS {
$arg_list = func_get_args();
}
$searchString = array_shift($arg_list);
$str_to_check = substr($searchString, 0, strpos($searchString, '.'));
$str_to_check = str_replace($wpdb->prefix, '', $str_to_check);
if ($str_to_check && in_array(trim($str_to_check), $wpdb->tables)) return;
for ($i = 0; $i < $numArgs-1; $i++) {
if ($searchString === strtolower($arg_list[$i])) {
return $i + 1;
@ -590,7 +590,6 @@ class PDOSQLiteUDFS {
$unsigned_int_data = sprintf('%u', $address);
return $unsigned_int_data;
}
/**
* Method to emulate MySQL DATEDIFF() function.
*
@ -680,8 +679,8 @@ class PDOSQLiteUDFS {
* @return string representing the version number: major_version.minor_version
*/
public function version() {
// global $required_mysql_version;
// return $required_mysql_version;
//global $required_mysql_version;
//return $required_mysql_version;
return '5.5';
}
}

View File

@ -68,7 +68,7 @@ function wp_install($blog_title, $user_name, $user_email, $public, $deprecated =
;// Your server is Apache. Nothing to do more.
} else {
$server_message = sprintf('Your webserver doesn\'t seem to be Apache. So the database directory access restriction by the .htaccess file may not function. We strongly recommend that you should restrict the access to the directory %s in some other way.', FQDBDIR);
echo '<div style="position: absolute; margin-top: 250px; width: 700px; border: .5px dashed rgb(0, 0, 0);"><p style="margin: 10px;">';
echo '<div style="position: absolute; margin-top: 350px; width: 700px; border: .5px dashed rgb(0, 0, 0);"><p style="margin: 10px;">';
echo $server_message;
echo '</p></div>';
}

View File

@ -12,7 +12,7 @@ if (!defined('ABSPATH')) {
die();
}
require_once PDODIR . 'pdoengine.class.php';
require_once PDODIR . 'install.php';
//require_once PDODIR . 'install.php';
if (!defined('SAVEQUERIES')){
define ('SAVEQUERIES', false);
@ -43,7 +43,7 @@ class PDODB extends wpdb {
*
* @see wpdb::__construct()
*/
function __construct() {
public function __construct() {
register_shutdown_function(array($this, '__destruct'));
if (WP_DEBUG)
@ -60,7 +60,7 @@ class PDODB extends wpdb {
*
* @see wpdb::__destruct()
*/
function __destruct() {
public function __destruct() {
return true;
}
@ -71,7 +71,7 @@ class PDODB extends wpdb {
*
* @see wpdb::set_charset()
*/
function set_charset($dbh, $charset = null, $collate = null) {
public function set_charset($dbh, $charset = null, $collate = null) {
if ( ! isset( $charset ) )
$charset = $this->charset;
if ( ! isset( $collate ) )
@ -82,7 +82,7 @@ class PDODB extends wpdb {
*
* @see wpdb::set_sql_mode()
*/
function set_sql_mode($modes = array()) {
public function set_sql_mode($modes = array()) {
unset($modes);
return;
}
@ -93,7 +93,7 @@ class PDODB extends wpdb {
*
* @see wpdb::select()
*/
function select($db, $dbh = null) {
public function select($db, $dbh = null) {
if (is_null($dbh))
$dbh = $this->dbh;
$this->ready = true;
@ -116,7 +116,18 @@ class PDODB extends wpdb {
function _real_escape($string) {
return addslashes($string);
}
/**
* Method to dummy out wpdb::esc_like() function.
*
* WordPress 4.0.0 introduced esc_like() function that adds backslashes to %,
* underscore and backslash, which is not interpreted as escape character
* by SQLite. So we override it and dummy out this function.
*
* @see wpdb::esc_like()
*/
public function esc_like($text) {
return $text;
}
/**
* Method to put out the error message.
*
@ -124,7 +135,7 @@ class PDODB extends wpdb {
*
* @see wpdb::print_error()
*/
function print_error($str = '') {
public function print_error($str = '') {
global $EZSQL_ERROR;
if (!$str) {
@ -172,7 +183,7 @@ class PDODB extends wpdb {
*
* @see wpdb::flush
*/
function flush() {
public function flush() {
$this->last_result = array();
$this->col_info = null;
$this->last_query = null;
@ -187,7 +198,7 @@ class PDODB extends wpdb {
*
* @see wpdb::db_connect()
*/
function db_connect($allow_bail=true) {
public function db_connect($allow_bail=true) {
if (WP_DEBUG) {
$this->dbh = new PDOEngine();
} else {
@ -200,15 +211,14 @@ class PDODB extends wpdb {
$this->bail(sprintf(__("<h1>Error establlishing a database connection</h1><p>We have been unable to connect to the specified database. <br />The error message received was %s"), $this->dbh->errorInfo()));
return;
}
$is_enabled_foreign_keys = @$this->get_var('PRAGMA foreign_keys');
if ($is_enabled_foreign_keys == '0') @$this->query('PRAGMA foreign_keys = ON');
$this->has_connected = true;
$this->ready = true;
}
/**
* Method to dummy out wpdb::check_connection()
*
*/
function check_connection($allow_bail=true) {
public function check_connection($allow_bail=true) {
return true;
}
/**
@ -219,7 +229,7 @@ class PDODB extends wpdb {
*
* @see wpdb::query()
*/
function query($query) {
public function query($query) {
if (!$this->ready)
return false;
@ -251,7 +261,7 @@ class PDODB extends wpdb {
}
if (preg_match('/^\\s*(create|alter|truncate|drop|optimize)\\s*/i', $query)) {
// $return_val = $this->result;
//$return_val = $this->result;
$return_val = $this->dbh->get_return_value();
} elseif (preg_match('/^\\s*(insert|delete|update|replace)\s/i', $query)) {
$this->rows_affected = $this->dbh->get_affected_rows();
@ -267,7 +277,14 @@ class PDODB extends wpdb {
return $return_val;
}
/**
* Method for future use?
*
* WordPress 3.9 separated the method to execute real query from query() function.
* This is for the restoration from the case that nothing returns from database.
* But this is necessary because we aleady did error manipulations in
* pdoengine.class.php. So we don't use this function.
*
* @access private
*/
private function _do_query($query) {
if (defined('SAVEQUERIES') && SAVEQUERIES) {
@ -301,7 +318,7 @@ class PDODB extends wpdb {
*
* @see wpdb::has_cap()
*/
function has_cap($db_cap) {
public function has_cap($db_cap) {
switch(strtolower($db_cap)) {
case 'collation':
case 'group_concat':
@ -322,9 +339,9 @@ class PDODB extends wpdb {
*
* @see wpdb::db_version()
*/
function db_version() {
// global $required_mysql_version;
// return $required_mysql_version;
public function db_version() {
//global $required_mysql_version;
//return $required_mysql_version;
return '5.5';
}
}

View File

@ -26,6 +26,12 @@ class PDOEngine extends PDO {
* @var unsigned integer
*/
public $found_rows_result = null;
/**
* Class variable used for query with ORDER BY FIELD()
*
* @var array of the object
*/
public $pre_ordered_results = null;
/**
* Class variable to store the rewritten queries.
*
@ -154,81 +160,104 @@ class PDOEngine extends PDO {
/**
* Constructor
*
* Create PDO object, set user defined functions and initialize other settings.
* Don't use parent::__construct() because this class does not only returns
* PDO instance but many others jobs.
*
* Constructor definition is changed since version 1.7.1.
*
* @param none
*/
function __construct() {
register_shutdown_function(array($this, '__destruct'));
if (is_file(FQDB)) {
$this->prepare_directory();
}
$dsn = 'sqlite:' . FQDB;
if (isset($GLOBALS['@pdo'])) {
$this->pdo = $GLOBALS['@pdo'];
} else {
$locked = false;
$status = 0;
do {
try {
$this->pdo = new PDO($dsn, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
require_once UDF_FILE;
new PDOSQLiteUDFS($this->pdo);
$GLOBALS['@pdo'] = $this->pdo;
} catch (PDOException $ex) {
$status = $ex->getCode();
if ($status == 5 || $status == 6) {
$locked = true;
} else {
$err_message = $ex->getMessage();
}
}
} while ($locked);
if ($status > 0) {
$message = 'Database initialization error!<br />' .
'Code: ' . $status . '<br />Error Message: ' . $err_message;
$this->set_error(__LINE__, __FILE__, $message);
return false;
}
}
$this->init();
}
/**
* Destructor
*
* If SQLITE_MEM_DEBUG constant is defined, append information about
* memory usage into database/mem_debug.txt.
*
* This definition is changed since version 1.7.
*
* @return boolean
*/
function __destruct() {
$this->pdo = null;
if (defined('SQLITE_MEM_DEBUG') && SQLITE_MEM_DEBUG) {
$max = ini_get('memory_limit');
if (is_null($max)) {
$message = sprintf("[%s] Memory_limit is not set in php.ini file.", date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']));
file_put_contents(FQDBDIR . 'mem_debug.txt', $message, FILE_APPEND);
return true;
}
if (stripos($max, 'M') !== false) {
$max = (int) $max * 1024 * 1024;
}
$peak = memory_get_peak_usage(true);
$used = round((int) $peak / (int) $max * 100, 2);
if ($used > 90) {
$message = sprintf("[%s] Memory peak usage warning: %s %% used. (max: %sM, now: %sM)\n", date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']), $used, $max, $peak);
file_put_contents(FQDBDIR . 'mem_debug.txt', $message, FILE_APPEND);
}
}
//$this->pdo = null;
return true;
}
/**
* Method to initialize database, executed in the contructor.
*
* It checks if there's a database directory and database file, creates the tables,
* and binds the user defined function to the pdo object.
* It checks if WordPress is in the installing process and does the required
* jobs. SQLite library version specific settings are also in this function.
*
* Some developers use WP_INSTALLING constant for other purposes, if so, this
* function will do no harms.
*
* @return boolean
*/
private function init() {
$dsn = 'sqlite:' . FQDB;
$result = $this->prepare_directory();
if (!$result) return false;
if (is_file(FQDB)) {
$locked = false;
do {
try {
if ($locked) $locked = false;
$this->pdo = new PDO(
$dsn, // data source name
null, // user name
null, // user password
array( // PDO options
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
if (defined('WP_INSTALLING') && WP_INSTALLING) {
$statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'");
$number_of_tables = $statement->fetchColumn(0);
$statement = null;
if ($number_of_tables == 0) {
$this->make_sqlite_tables();
if ($number_of_tables == 0) $this->make_sqlite_tables();
}
} catch (PDOException $err) {
$status = $err->getCode();
// code 5 => The database file is locked
// code 6 => A table in the database is locked
if ($status == 5 || $status == 6) {
$locked = true;
} else {
$message = 'Database connection error!<br />';
$message .= sprintf("Error message is: %s", $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
}
} while ($locked);
require_once UDF_FILE;
new PDOSQLiteUDFS($this->pdo);
if (version_compare($this->get_sqlite_version(), '3.7.11', '>=')) {
$this->can_insert_multiple_rows = true;
}
} else { // database file is not found, so we make it and create tables...
try {
$this->pdo = new PDO($dsn, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch (PDOException $err) {
$message = 'Database initialization error!<br />';
$message .= sprintf("Error message is: %s", $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
$this->make_sqlite_tables();
}
$statement = $this->pdo->query('PRAGMA foreign_keys');
if ($statement->fetchColumn(0) == '0') $this->pdo->query('PRAGMA foreign_keys = ON');
}
/**
@ -240,7 +269,7 @@ class PDOEngine extends PDO {
global $wpdb;
$u = umask(0000);
if (!is_dir(FQDBDIR)) {
if (!@mkdir(FQDBDIR, 0707, true)) {
if (!@mkdir(FQDBDIR, 0704, true)) {
umask($u);
$message = 'Unable to create the required directory! Please check your server settings.';
wp_die($message, 'Error!');
@ -327,9 +356,9 @@ class PDOEngine extends PDO {
if (!is_null($this->found_rows_result)) {
$this->num_rows = $this->found_rows_result;
$_column['FOUND_ROWS()'] = $this->num_rows;
// foreach ($this->found_rows_result[0] as $key => $value) {
// $_column['FOUND_ROWS()'] = $value;
// }
//foreach ($this->found_rows_result[0] as $key => $value) {
//$_column['FOUND_ROWS()'] = $value;
//}
$column[] = new ObjectArray($_column);
$this->results = $column;
$this->found_rows_result = null;
@ -370,6 +399,12 @@ class PDOEngine extends PDO {
default:
$engine = $this->prepare_engine($this->query_type);
$this->rewritten_query = $engine->rewrite_query($query, $this->query_type);
if (!is_null($this->pre_ordered_results)) {
$this->results = $this->pre_ordered_results;
$this->num_rows = $this->return_value = count($this->results);
$this->pre_ordered_results = null;
break;
}
$this->queries[] = "Rewritten:\n$this->rewritten_query";
$this->extract_variables();
$statement = $this->prepare_query();
@ -495,7 +530,7 @@ class PDOEngine extends PDO {
}
$output = '<div style="clear:both">&nbsp;</div>';
if ($this->is_error === false){
// return $output;
//return $output;
return '';
}
$output .= "<div class=\"queries\" style=\"clear:both; margin_bottom:2px; border: red dotted thin;\">Queries made or created this session were<br/>\r\n\t<ol>\r\n";
@ -676,7 +711,7 @@ class PDOEngine extends PDO {
case 'desc':
case 'check':
case 'analyze':
// case "foundrows":
//case "foundrows":
$this->num_rows = count($this->_results);
$this->return_value = $this->num_rows;
break;
@ -714,6 +749,10 @@ class PDOEngine extends PDO {
//long queries can really kill this
$pattern = '/(?<!\\\\)([\'"])(.*?)(?<!\\\\)\\1/imsx';
$_limit = $limit = ini_get('pcre.backtrack_limit');
// if user's setting is more than default * 10, make PHP do the job.
if ($limit > 10000000) {
$query = preg_replace_callback($pattern, array($this, 'replace_variables_with_placeholders'), $this->rewritten_query);
} else {
do {
if ($limit > 10000000) {
$message = 'The query is too big to parse properly';
@ -724,10 +763,11 @@ class PDOEngine extends PDO {
$query = preg_replace_callback($pattern, array($this,'replace_variables_with_placeholders'), $this->rewritten_query);
}
$limit = $limit * 10;
} while (empty($query));
} while (is_null($query));
//reset the pcre.backtrack_limist
ini_set('pcre.backtrack_limit', $_limit);
}
$this->queries[] = "With Placeholders:\n" . $query;
$this->prepared_query = $query;
}
@ -926,7 +966,7 @@ class PDOEngine extends PDO {
$rewritten_query = $engine->rewrite_query($query);
$reason = 0;
$message = '';
// $queries = explode(";", $this->rewritten_query);
//$queries = explode(";", $this->rewritten_query);
try {
$this->beginTransaction();
foreach ($rewritten_query as $single_query) {

View File

@ -48,6 +48,18 @@ class PDOSQLiteDriver {
* @var boolean
*/
private $rewrite_between = false;
/**
* Variable to check how many times rewriting BETWEEN is needed.
*
* @var integer
*/
private $num_of_rewrite_between = 0;
/**
* Variable to check order by field() with column data.
*
* @var boolean
*/
private $orderby_field = false;
/**
* Method to rewrite a query string for SQLite to execute.
*
@ -91,6 +103,7 @@ class PDOSQLiteDriver {
//$this->rewrite_boolean();
$this->fix_date_quoting();
$this->rewrite_between();
$this->handle_orderby_field();
break;
case 'insert':
//$this->safe_strip_backticks();
@ -102,7 +115,7 @@ class PDOSQLiteDriver {
case 'update':
//$this->safe_strip_backticks();
$this->rewrite_update_ignore();
// $this->_rewrite_date_sub();
//$this->_rewrite_date_sub();
$this->rewrite_limit_usage();
$this->rewrite_order_by_usage();
$this->rewrite_regexp();
@ -184,6 +197,10 @@ class PDOSQLiteDriver {
}
if (stripos($token, 'BETWEEN') !== false) {
$this->rewrite_between = true;
$this->num_of_rewrite_between++;
}
if (stripos($token, 'ORDER BY FIELD') !== false) {
$this->orderby_field = true;
}
}
}
@ -385,7 +402,6 @@ class PDOSQLiteDriver {
* @access private
*/
private function handle_describe_query(){
// $this->_query = "select 1=1";
$pattern = '/^\\s*(DESCRIBE|DESC)\\s*(.*)/i';
if (preg_match($pattern, $this->_query, $match)) {
$tablename = preg_replace('/[\';]/', '', $match[2]);
@ -429,7 +445,7 @@ class PDOSQLiteDriver {
if (stripos($opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT') !== false) return;
}
if (stripos($this->_query, '(select') === false) {
$this->_query = preg_replace('/\\s*ORDER\\s*BY\\s*.*$/i', '', $this->_query);
$this->_query = preg_replace('/\\s+ORDER\\s+BY\\s*.*$/i', '', $this->_query);
}
}
/**
@ -619,7 +635,6 @@ class PDOSQLiteDriver {
$val = trim(array_shift($ins_data_array));
$ins_data_assoc[trim($col)] = $val;
}
// $ins_data_assoc = array_combine($col_array, $ins_array);
$condition = '';
foreach ($unique_keys_for_cond as $unique_key) {
if (strpos($unique_key, ',') !== false) {
@ -635,7 +650,6 @@ class PDOSQLiteDriver {
continue;
}
}
// $condition = rtrim($condition, ' AND ');
} else {
$col = trim($unique_key);
if (isset($ins_data_assoc[$col])) {
@ -653,7 +667,6 @@ class PDOSQLiteDriver {
$this->_query = 'INSERT INTO '.$table_name.' '.$insert_data;
return;
} else {
// change (col, col...) values (data, data...) to array(col=>data, col=>data...)
if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2)) {
$col_array = explode(',', $match_2[1]);
$ins_array = explode(',', $match_2[2]);
@ -664,8 +677,6 @@ class PDOSQLiteDriver {
$ins_array_assoc[$col] = $val;
}
}
// change col = data, col = data to array(col=>data, col=>data)
// some plugins have semi-colon at the end of the query
$update_data = rtrim($update_data, ';');
$tmp_array = explode(',', $update_data);
foreach ($tmp_array as $pair) {
@ -674,7 +685,6 @@ class PDOSQLiteDriver {
$value = trim($value);
$update_array_assoc[$col] = $value;
}
// change array(col=>values(col)) to array(col=>data)
foreach ($update_array_assoc as $key => &$value) {
if (preg_match('/^VALUES\\s*\((.*)\)$/im', $value, $match_3)) {
$col = trim($match_3[1]);
@ -697,18 +707,11 @@ class PDOSQLiteDriver {
$update_strings = rtrim($update_strings, ',');
$unique_where = array_unique($where_array, SORT_REGULAR);
$where_string = ' WHERE ' . implode(' AND ', $unique_where);
// $where_string = ' WHERE ' . rtrim($where_string, ',');
$update_query = 'UPDATE ' . $table_name . ' SET ' . $update_strings . $where_string;
$this->_query = $update_query;
}
}
}
// else {
// $pattern = '/ ON DUPLICATE KEY UPDATE.*$/im';
// $replace_query = preg_replace($pattern, '', $this->_query);
// $replace_query = str_ireplace('INSERT ', 'INSERT OR REPLACE ', $replace_query);
// $this->_query = $replace_query;
// }
}
/**
* Method to rewrite BETWEEN A AND B clause.
@ -720,15 +723,71 @@ class PDOSQLiteDriver {
*/
private function rewrite_between() {
if (!$this->rewrite_between) return;
$pattern = '/\\s*(CAST\(.+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims';
$pattern = '/\\s*(CAST\([^\)]+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims';
do {
if (preg_match($pattern, $this->_query, $match)) {
$column_name = trim($match[1]);
$min_value = trim($match[2]);
$max_value = trim($match[3]);
$max_value = rtrim($max_value);
$replacement = " $column_name >= $min_value AND $column_name <= $max_value";
$replacement = " ($column_name >= $min_value AND $column_name <= $max_value)";
$this->_query = str_ireplace($match[0], $replacement, $this->_query);
}
$this->num_of_rewrite_between--;
} while ($this->num_of_rewrite_between > 0);
}
/**
* Method to handle ORDER BY FIELD() clause.
*
* When FIELD() function has column name to compare, we can't rewrite it with
* use defined functions. When this function detect column name in the argument,
* it creates another instance, does the query withuot ORDER BY clause and gives
* the result array sorted to the main instance.
*
* If FIELD() function doesn't have column name, it will use the user defined
* function. usort() function closure function to compare the items.
*
* @access private
*/
private function handle_orderby_field() {
if (!$this->orderby_field) return;
global $wpdb;
$pattern = '/\\s+ORDER\\s+BY\\s+FIELD\\s*\(\\s*([^\)]+?)\\s*\)/i';
if (preg_match($pattern, $this->_query, $match)) {
global $flipped;
$params = explode(',', $match[1]);
$params = array_map('trim', $params);
$tbl_col = array_shift($params);
$flipped = array_flip($params);
$tbl_name = substr($tbl_col, 0, strpos($tbl_col, '.'));
$tbl_name = str_replace($wpdb->prefix, '', $tbl_name);
if ($tbl_name && in_array($tbl_name, $wpdb->tables)) {
$query = str_replace($match[0], '', $this->_query);
$_wpdb = new PDODB();
$results = $_wpdb->get_results($query);
$_wpdb = null;
/* $compare = function($a, $b) { */
/* global $flipped; */
/* return $flipped[$a->ID] - $flipped[$b->ID]; */
/* }; */
/* usort($results, $compare); */
usort($results, array($this, 'orderby_callback'));
}
$wpdb->dbh->pre_ordered_results = $results;
}
}
/**
* Callback method for sorting
*
* As PHP 5.2 doesn't allow closure function, this callback procedure
* is necessary.
*
* @param queried object
* @access private
*/
private function orderby_callback($a, $b) {
global $flipped;
return $flipped[$a->ID] - $flipped[$b->ID];
}
/**
* Method to avoid DELETE with JOIN statement.
@ -743,11 +802,22 @@ class PDOSQLiteDriver {
*/
private function delete_workaround() {
global $wpdb;
// $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (option_name) WHERE o2.option_id > o1.option_id";
$pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2";
$pattern2 = "DELETE a, b FROM $wpdb->sitemeta AS a, $wpdb->sitemeta AS b";
$rewritten = "DELETE FROM $wpdb->options WHERE option_id IN (SELECT MIN(option_id) FROM $wpdb->options GROUP BY option_name HAVING COUNT(*) > 1)";
if (stripos($this->_query, $pattern) !== false) {
$this->_query = $rewritten;
} else if (stripos($this->_query, $pattern2) !== false) {
$time = time();
$prep_query = "SELECT a.meta_id AS aid, b.meta_id AS bid FROM $wpdb->sitemeta AS a INNER JOIN $wpdb->sitemeta AS b ON a.meta_key='_site_transient_timeout_'||substr(b.meta_key, 17) WHERE b.meta_key='_site_transient_'||substr(a.meta_key, 25) AND a.meta_value < $time";
$_wpdb = new PDODB();
$ids = $_wpdb->get_results($prep_query);
foreach ($ids as $id) {
$ids_to_delete[] = $id->aid;
$ids_to_delete[] = $id->bid;
}
$rewritten = "DELETE FROM $wpdb->sitemeta WHERE meta_id IN (".implode(',', $ids_to_delete).")";
$this->_query = $rewritten;
}
}
/**

View File

@ -33,7 +33,7 @@ class AlterQuery {
$command = str_ireplace($match[0], '', $query);
$tmp_tokens['query_type'] = trim($match[1]);
$tmp_tokens['table_name'] = trim($match[2]);
// $command_array = $this->split_multiple($command);
//$command_array = $this->split_multiple($command);
$command_array = explode(',', $command);
$single_command = array_shift($command_array);
@ -48,7 +48,6 @@ class AlterQuery {
$this->_query = 'SELECT 1=1';
return $this->_query;
}
// foreach ($tokens as $token) {
$command_name = strtolower($tokens['command']);
switch ($command_name) {
case 'add column': case 'rename to': case 'add index': case 'drop index':
@ -72,7 +71,6 @@ class AlterQuery {
default:
break;
}
// }
if (!is_array($tmp_query)) {
$this->_query[] = $tmp_query;
} else {

View File

@ -71,6 +71,7 @@ class CreateQuery{
return $this->_query;
}
$this->strip_backticks();
$this->quote_illegal_field();
$this->get_table_name();
$this->rewrite_comments();
$this->rewrite_field_types();
@ -106,6 +107,10 @@ class CreateQuery{
/**
* Method to change the MySQL field types to SQLite compatible types.
*
* If column name is the same as the key value, e.g. "date" or "timestamp",
* and the column is on the top of the line, we add a single quote and avoid
* to be replaced. But this doesn't work if that column name is in the middle
* of the line.
* Order of the key value is important. Don't change it.
*
* @access private
@ -129,8 +134,14 @@ class CreateQuery{
'mediumblob' => 'blob', 'mediumtext' => 'text',
'longblob' => 'blob', 'longtext' => 'text'
);
foreach ($array_types as $o=>$r){
$pattern = "/\\b(?<!`)$o\\b\\s*(\([^\)]*\)*)?\\s*/ims";
foreach ($array_types as $o => $r){
if (preg_match("/^\\s*(?<!')$o\\s+(.+$)/im", $this->_query, $match)) {
$ptrn = "/$match[1]/im";
$replaced = str_ireplace($ptrn, '#placeholder#', $this->_query);
$replaced = str_ireplace($o, "'{$o}'", $replaced);
$this->_query = str_replace('#placeholder#', $ptrn, $replaced);
}
$pattern = "/\\b(?<!')$o\\b\\s*(\([^\)]*\)*)?\\s*/ims";
if (preg_match("/^\\s*.*?\\s*\(.*?$o.*?\)/im", $this->_query)) {
;
} else {
@ -287,7 +298,7 @@ class CreateQuery{
* @access private
*/
private function rewrite_key(){
$this->_query = preg_replace_callback('/,\\s*(KEY|INDEX)\\s*(\\w+)?\\s*(\(.*(?<!\\d)\))/im', array($this, '_rewrite_key'), $this->_query);
$this->_query = preg_replace_callback('/,\\s*(KEY|INDEX)\\s*(\\w+)?\\s*(\(.+\))/im', array($this, '_rewrite_key'), $this->_query);
}
/**
* Callback method for rewrite_key.
@ -337,7 +348,7 @@ class CreateQuery{
* @return array
* @access private
*/
private function post_process(){
private function post_process() {
$mainquery = $this->_query;
do{
$count = 0;
@ -393,5 +404,13 @@ class CreateQuery{
$patterns = array($pattern_charset, $pattern_collate1, $pattern_collate2);
$this->_query = preg_replace($patterns, '', $this->_query);
}
/**
* Method to quote illegal field name for SQLite
*
* @access private
*/
private function quote_illegal_field() {
$this->_query = preg_replace("/^\\s*(?<!')(default|values)/im", "'\\1'", $this->_query);
}
}
?>

View File

@ -6,8 +6,8 @@ Tags: database, SQLite, PDO
Author: Kojima Toshiyasu
Author URI: http://dogwood.skr.jp/
Requires at least: 3.3
Tested up to: 3.9
Stable tag: 1.6.3
Tested up to: 4.1.1
Stable tag: 1.8
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -115,6 +115,10 @@ SQLite に戻りたいときには、この行を次のように変更するか
== よくある質問 ==
= 「データベース接続エラー」でインストールが止まります =
wp-config.php を手動で作成することが必要です。WordPress に作らせようとすると、途中でインストールが止まります。
= データベース・ファイルが作られません =
ディレクトリやファイルを作るのに失敗するのは、多くの場合、PHPにその権限がないことが原因です。サーバの設定を確認するか、管理者に聞いてみてください。
@ -160,10 +164,23 @@ SQLite に戻りたいときには、この行を次のように変更するか
== Upgrade Notice ==
メタクエリを使うときのバグを修正しました。自動アップグレードで失敗するようなら、FTPを使っての手動アップグレードを試してみてください。
WordPress 4.1.1 での動作チェックをして、いくつかのバグを修正しました。アップグレードをお勧めします。自動アップグレードで失敗するようなら、FTPを使っての手動アップグレードを試してみてください。
== Changelog ==
= 1.8 (2014-03-06) =
* インストール・プロセスのバグを修正しました。
* index query の正規表現を修正しました。いくつかのプラグインが影響を受けるかもしれません。
* PHP 5.2.x で動作しない部分を修正しました。
= 1.7 (2014-09-05) =
* エディタ画面で、添付ファイルの並べ替えができなかったのを修正しました。
* CREATE クエリのバグを修正しました。
* 128x128 アイコンと 256x256 アイコンを追加しました。
* pcre.backtrack_limit が大きな値に設定されている場合、それを使うようにしました。
* メタクエリの BETWEEN の扱いを変更しました。
* WordPress 4.0 での動作チェックをしました。
= 1.6.3 (2014-05-10) =
* BETWEEN 比較をするメタクエリのバグを修正しました。
* スペイン語カタログを追加しました。

View File

@ -6,8 +6,8 @@ Tags: database, SQLite, PDO
Author: Kojima Toshiyasu
Author URI: http://dogwood.skr.jp/
Requires at least: 3.3
Tested up to: 3.9
Stable tag: 1.6.3
Tested up to: 4.1.1
Stable tag: 1.8
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -21,7 +21,7 @@ SQLite Integration is a successor to [PDO for WordPress](http://wordpress.org/ex
= Features =
SQLite Integration is a database access engine program. So it's not like the other plugins. It must be used to install WordPress. Please read the install section. And see more detailed instruction in the [SQLite Integration Page](http://dogwood.skr.jp/wordpress/sqlite-integration/).
SQLite Integration is a database access engine program, which means it's not like the other plugins. It must be used to install WordPress. Please read the install section. And see more detailed instruction in the [SQLite Integration Page](http://dogwood.skr.jp/wordpress/sqlite-integration/).
Once you succeed in installing WordPress, you can use it just like the other systems using MySQL. Optionally, this plugin provides the feature to temporarily change the database to MySQL and come back to SQLite, which may help developers test their sites on the local machines without MySQL.
@ -115,6 +115,10 @@ If export or import fails for some reason, please visit our site and try another
== Frequently Asked Questions ==
= Install stops with 'Error establishing a database connection' =
It is required that you should prepare wp-config.php manually. If you try to make WordPress create wp-config.php, you'll get that message and can't continue install process.
= Database file is not created =
The reason of failure in creating directory or files is often that PHP is not allowed to craete them. Please check your server setting or ask the administrator.
@ -158,10 +162,22 @@ This plugin doesn't support 'WP_PLUGIN_URL' constant.
== Upgrade Notice ==
Fixed the bug about meta query with BETWEEN comparison which may cause some plugins to work correctly. Upgrade is recommended. When auto upgrading fails, please try manual upgrade via FTP.
WordPress 4.1.1 compatibility is checked and some bugs are fixed. Upgrade is recommended. When auto upgrading fails, please try manual upgrade via FTP.
== Changelog ==
= 1.8 (2015-03-06) =
* Fixed the bug about install process algorithm.
* Fixed the index query regexp, which may cause a problem to some plugins.
* Solved PHP 5.2.x compatibility issue.
= 1.7 (2014-09-05) =
* Fixed the bug about changing the order of the attachment file in the editor screen.
* Fixed the bug about the manipulation of CREATE query.
* Added an 128x128 icon and 256x256 icon.
* Change for checking the user defined value of pcre.backtrack_limit and using it.
* WordPress 4.0 compatibilitiy checked.
= 1.6.3 (2014-05-10) =
* Fixed the bug about manipulating meta query with BETWEEN comparison.
* Added the Spanish langugae support.

View File

@ -22,7 +22,7 @@ function make_db_sqlite() {
include_once ABSPATH . 'wp-admin/includes/schema.php';
$index_array = array();
// ob_end_clean();
//ob_end_clean();
$table_schemas = wp_get_db_schema();
$queries = explode (";", $table_schemas);
$query_parser = new CreateQuery();
@ -47,10 +47,10 @@ function make_db_sqlite() {
$index_queries = $rewritten_query;
$table_query = trim($table_query);
$pdo->exec($table_query);
// foreach($rewritten_query as $single_query) {
// $single_query = trim($single_query);
// $pdo->exec($single_query);
// }
//foreach($rewritten_query as $single_query) {
// $single_query = trim($single_query);
// $pdo->exec($single_query);
//}
} else {
$rewritten_query = trim($rewritten_query);
$pdo->exec($rewritten_query);

View File

@ -4,7 +4,7 @@ Plugin Name: SQLite Integration
Plugin URI: http://dogwood.skr.jp/wordpress/sqlite-integration/
Description: SQLite Integration is the plugin that enables WordPress to use SQLite. If you don't have MySQL and want to build a WordPress website, it's for you.
Author: Kojima Toshiyasu
Version: 1.6.3
Version: 1.8
Author URI: http://dogwood.skr.jp
Text Domain: sqlite-integration
Domain Path: /languages
@ -44,7 +44,7 @@ $siteurl = get_option('siteurl');
/*
* Defines basic constants.
*/
define('SQLITE_INTEGRATION_VERSION', '1.6.2');
define('SQLITE_INTEGRATION_VERSION', '1.8');
define('SQLiteDir', dirname(plugin_basename(__FILE__)));
define('SQLiteFilePath', dirname(__FILE__));
define('SQLiteDirName', basename(SQLiteFilePath));
@ -109,6 +109,7 @@ class SQLiteIntegration {
register_activation_hook(__FILE__, array($this, 'install'));
}
if (function_exists('register_deactivation_hook')) {
;
}
if (function_exists('register_uninstall_hook')) {
register_uninstall_hook(__FILE__, array('SQLiteIntegration', 'uninstall'));
@ -268,11 +269,11 @@ class SQLiteIntegration {
*/
function textdomain_init() {
global $utils;
// $current_locale = get_locale();
// if (!empty($current_locale)) {
// $moFile = dirname(__FILE__) . "/languages/sqlite-wordpress-" . $current_locale . ".mo";
// if(@file_exists($moFile) && is_readable($moFile)) load_textdomain('sqlite-wordpress', $moFile);
// }
//$current_locale = get_locale();
//if (!empty($current_locale)) {
// $moFile = dirname(__FILE__) . "/languages/sqlite-wordpress-" . $current_locale . ".mo";
// if(@file_exists($moFile) && is_readable($moFile)) load_textdomain('sqlite-wordpress', $moFile);
//}
load_plugin_textdomain($utils->text_domain, false, SQLiteDir.'/languages/');
}

View File

@ -39,7 +39,7 @@ class SQLiteIntegrationUtils {
return;
$notice_string = __('Upgrading Notice: To finish upgrading, please activate SQLite Integration and go Setting >> SQLite Integration >> Miscellaneous, and click the button &quot;update&quot; at the bottom of the page. Or else replace wp-content/db.php with the one in sqlite-integration directory manually.', 'sqlite-integration');
$current_version = defined('SQLITE_INTEGRATION_VERSION') ? SQLITE_INTEGRATION_VERSION : '';
if (version_compare($current_version, '1.6.2', '=')) return;
if (version_compare($current_version, '1.8', '=')) return;
$version = '';
if (defined('WP_CONTENT_DIR')) {
$path = WP_CONTENT_DIR . '/db.php';