Files
selima-perl/lib/php/monica/sql.inc.php
2026-03-10 21:31:43 +08:00

440 lines
11 KiB
PHP

<?php
// File name: sql.inc.php
// Description: PHP meta subroutines to handle SQL actions
// Date: 2004-05-22
// Author: imacat <imacat@pristine.com.tw>
// Copyright: Copyright (C) 2004-2007 Pristine Communications
// Set the include path
if (!defined("INCPATH_SET")) {
require_once dirname(__FILE__) . "/incpath.inc.php";
}
// Referenced subroutines with high precedence
require_once "monica/sqlconst.inc.php";
// Referenced subroutines
require_once "monica/mysql.inc.php";
require_once "monica/postgres.inc.php";
// Settings
// Settings are moved to sqlconst.inc.php
// sql_connect: Connect to the SQL database
function sql_connect()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return xpg_connect();
break;
case SQL_MYSQL:
return xmysql_connect();
break;
}
}
// sql_close: Disconnect from the SQL database
function sql_close()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return xpg_close();
case SQL_MYSQL:
return xmysql_close();
}
}
/////////////////////////
// Concurrency Control: Transactions and Locks
/////////////////////////
// sql_begin: Begin an SQL transaction
function sql_begin()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_begin();
case SQL_MYSQL:
return mysql_begin();
}
}
// sql_commit: Commit an SQL transaction
function sql_commit()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_commit();
case SQL_MYSQL:
return mysql_commit();
}
}
// sql_rollback: Rollback an SQL transaction
function sql_rollback()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_rollback();
case SQL_MYSQL:
return mysql_rollback();
}
}
// sql_lock: Lock and unlock the SQL tables
function sql_lock($locks = null)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_lock($locks);
case SQL_MYSQL:
return mysql_lock($locks);
}
}
// sql_query: Do an SQL query and report the error
function sql_query($query)
{
static $use_mtime;
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
if (!isset($use_mtime)) {
$use_mtime = in_array("mtime", pg_tables());
}
$result = xpg_query($query);
// Update the mtime
if ($use_mtime) {
if (preg_match("/^(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+(\S+)/i", $query, $m)) {
$table = $m[1];
$select_mtime = "SELECT * FROM mtime"
. " WHERE tabname='" . pg_escape_string($table) . "';\n";
$result_mtime = xpg_query($select_mtime);
// Found
if (pg_num_rows($result_mtime) == 1) {
// Update the mtime
$update = "UPDATE mtime SET mtime=now()"
. " WHERE tabname='" . pg_escape_string($table) . "';\n";
xpg_query($update);
// Not found
} else {
// Set the mtime
$insert = "INSERT INTO mtime (tabname, mtime) VALUES"
. "('" . pg_escape_string($table) . "', now());\n";
xpg_query($insert);
}
}
}
return $result;
case SQL_MYSQL:
if (!isset($use_mtime)) {
$use_mtime = in_array("mtime", mysql_tables());
}
$result = xmysql_query($query);
// Update the mtime
if ($use_mtime) {
if (preg_match("/^(?:INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+(\S+)/i", $query, $m)) {
$table = $m[1];
$select_mtime = "SELECT * FROM mtime"
. " WHERE tabname='" . mysql_escape_string($table) . "';\n";
$result_mtime = xmysql_query($select_mtime);
// Found
if (mysql_num_rows($result_mtime) == 1) {
// Update the mtime
$update = "UPDATE mtime SET mtime=now()"
. " WHERE tabname='" . mysql_escape_string($table) . "';\n";
xmysql_query($update);
// Not found
} else {
// Set the mtime
$insert = "INSERT INTO mtime (tabname, mtime) VALUES"
. "('" . mysql_escape_string($table) . "', now());\n";
xmysql_query($insert);
}
}
}
return $result;
}
}
// sql_seek: Move the SQL result pointer
function sql_seek($query, $offset)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_seek($query, $offset);
case SQL_MYSQL:
return mysql_seek($query, $offset);
}
}
// sql_num_rows: Return the number of rows
function sql_num_rows($result)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_num_rows($result);
case SQL_MYSQL:
return mysql_num_rows($result);
}
}
// sql_fetch_assoc: Return a row as an associative array
function sql_fetch_assoc($result)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return xpg_fetch_assoc($result);
case SQL_MYSQL:
return xmysql_fetch_assoc($result);
}
}
// sql_fetch_row: Return a row as an numeric array
function sql_fetch_row($result)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return xpg_fetch_row($result);
case SQL_MYSQL:
return xmysql_fetch_row($result);
}
}
// sql_tables: Return a list of available tables
function sql_tables($schema = null)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_tables($schema);
case SQL_MYSQL:
return mysql_tables($schema);
}
}
// sql_is_ml_table: Return if a table is multi-lingual
function sql_is_ml_table($table)
{
return (count(sql_cols_ml($table)) > 0);
}
// sql_cols: Return a list of available columns in a table
function sql_cols($table)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_cols($table);
case SQL_MYSQL:
return mysql_cols($table);
}
}
// sql_cols_ml: Return a list of multi-lingual columns in a table
function sql_cols_ml($table)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_cols_ml($table);
case SQL_MYSQL:
return mysql_cols_ml($table);
}
}
// sql_cols_nl: Return a list of columns without their multi-lingual
// deviants in a table
function sql_cols_nl($table)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_cols_nl($table);
case SQL_MYSQL:
return mysql_cols_nl($table);
}
}
// sql_cols_of_type: Return the columns in a certain data type
function sql_cols_of_type($result, $type, $format = SQL_FETCH_ASSOC)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_cols_of_type($result, $type, $format);
case SQL_MYSQL:
return mysql_cols_of_type($result, $type, $format);
}
}
// sql_col_lens: Return the column length in a table
function sql_col_lens($table)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_col_lens($table);
case SQL_MYSQL:
return mysql_col_lens($table);
}
}
// sql_strcat: Concatenate strings
function sql_strcat()
{
$strs = func_get_args();
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return call_user_func_array("pg_strcat", $strs);
case SQL_MYSQL:
return call_user_func_array("mysql_strcat", $strs);
}
}
// sql_lastupd: Obtain the last updated time of a list of tables
function sql_lastupd($tables)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_lastupd($tables);
case SQL_MYSQL:
return mysql_lastupd($tables);
}
}
// sql_dbsize: Obtain the size of the database
function sql_dbsize()
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_NONE:
return 0;
case SQL_POSTGRESQL:
return pg_dbsize();
case SQL_MYSQL:
return mysql_dbsize();
}
}
// sql_date: Return date in a predefined format
function sql_date($expr, $format)
{
$strs = func_get_args();
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_date($expr, $format);
case SQL_MYSQL:
return mysql_date($expr, $format);
}
}
// sql_re: Return the SQL regular expression operator
function sql_re()
{
$strs = func_get_args();
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_re();
case SQL_MYSQL:
return mysql_re();
}
}
// sql_escblob: Escape a piece of BLOB octet
function sql_escblob($blob)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_escape_bytea($blob);
case SQL_MYSQL:
return mysql_escape_string($blob);
}
}
// sql_esctext: Escape a piece of text
function sql_esctext($text)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
return pg_escape_string($text);
case SQL_MYSQL:
return mysql_escape_string($text);
}
}
// sql_strlen: Calculate the length of a text string
// MySQL once used strlen(), but now mb_strlen() since 4.1
function sql_strlen($text)
{
switch ($GLOBALS["SQL_DBTYPE"]) {
case SQL_POSTGRESQL:
case SQL_MYSQL:
return mb_strlen($text);
}
}
// sql_support: Return if this SQL supports views
function sql_support($feature)
{
switch ($feature) {
// If view is supported
// MySQL once did not support, but support now since 5.0
case SQL_FEATURE_VIEW:
return true;
// If boolean data type is supported
case SQL_FEATURE_BOOLEAN:
if ($GLOBALS["SQL_DBTYPE"] == SQL_MYSQL) {
return false;
}
return true;
// Default to yes. ^^; We assume everyone is a good guy
default:
return true;
}
}
// sql_is_true: Return the expression for a boolean true
function sql_is_true($expr)
{
if (!sql_support(SQL_FEATURE_BOOLEAN)) {
return "$expr IS NOT NULL";
}
return $expr;
}
// sql_is_false: Return the expression for a boolean false
function sql_is_false($expr)
{
if (!sql_support(SQL_FEATURE_BOOLEAN)) {
return "$expr IS NULL";
}
return "NOT $expr";
}
// sql_true: Return the boolean true value
function sql_true()
{
if (!sql_support(SQL_FEATURE_BOOLEAN)) {
return "''";
}
return "TRUE";
}
// sql_false: Return the boolean false value
function sql_false()
{
if (!sql_support(SQL_FEATURE_BOOLEAN)) {
return "NULL";
}
return "FALSE";
}
// sql_esclike: Escape a phrase by the LIKE matching rule
// Double quote should never be used, according to
// the column name rules in the SQL standard.
function sql_esclike($phrase)
{
$phrase = str_replace("\\", "\\\\\\\\", $phrase);
$phrase = str_replace("%", "\\\\%", $phrase);
$phrase = str_replace("_", "\\\\_", $phrase);
// By the SQL standard
$phrase = str_replace("'", "''", $phrase);
// Loose way that works for some overly-simple, non-standard DBMS, like MySQL
//$phrase = str_replace("'", "\\\\\\'", $phrase);
return $phrase;
}
?>