+ private static function queryv($query)
+ {
+ return new XDBResult(self::prepare($query));
+ }
+
+ public static function query()
+ {
+ return self::queryv(func_get_args());
+ }
+
+ public static function rawQuery($query)
+ {
+ return new XDBResult($query);
+ }
+
+ public static function format()
+ {
+ return self::prepare(func_get_args());
+ }
+
+ // Produce the SQL statement for setting/unsetting a flag
+ public static function changeFlag($fieldname, $flagname, $state)
+ {
+ if ($state) {
+ return XDB::format($fieldname . ' = CONCAT({?}, \',\', ' . $fieldname . ')', $flagname);
+ } else {
+ return XDB::format($fieldname . ' = REPLACE(' . $fieldname . ', {?}, \'\')', $flagname);
+ }
+ }
+
+ // Produce the SQL statement representing an array
+ public static function formatArray(array $array)
+ {
+ return self::escape($array);
+ }
+
+ const WILDCARD_EXACT = 0x00;
+ const WILDCARD_PREFIX = 0x01;
+ const WILDCARD_SUFFIX = 0x02;
+ const WILDCARD_CONTAINS = 0x03; // WILDCARD_PREFIX | WILDCARD_SUFFIX
+
+ // Produce a valid XDB argument that get formatted as a wildcard
+ // according to the given mode.
+ //
+ // Example:
+ // XDB::query("SELECT * FROM table WHERE field {?}", XDB::wildcard($text, WILDCARD_EXACT));
+ public static function wildcard($mode, $value)
+ {
+ return new XDBWildcard($value, $mode);
+ }
+
+ // Returns the SQL statement for a wildcard search.
+ public static function formatWildcards($mode, $text)
+ {
+ return XDB::wildcard($mode, $text)->format();
+ }
+
+ // Returns a FIELD(blah, 3, 1, 2) for use in an order with custom orders
+ public static function formatCustomOrder($field, $values)
+ {
+ return 'FIELD( ' . $field . ', ' . implode(', ', array_map(array('XDB', 'escape'), $values)) . ')';
+ }
+
+ public static function execute()
+ {
+ global $globals;
+ $args = func_get_args();
+ if ($globals->mode != 'rw' && !strpos($args[0], 'logger')) {
+ return;
+ }
+ return self::run(XDB::prepare($args));
+ }
+
+ public static function rawExecute($query)
+ {
+ global $globals;
+ if ($globals->mode != 'rw') {
+ return;
+ }
+ return self::run($query);
+ }
+
+ private static $inTransaction = false;
+ public static function startTransaction()
+ {
+ if (self::$inTransaction) {
+ throw new XDBException('START TRANSACTION', 'Already in a transaction');
+ }
+ self::$inTransaction = true;
+ self::rawExecute('SET AUTOCOMMIT = 0');
+ self::rawExecute('START TRANSACTION');
+ }
+
+ public static function commit()
+ {
+ self::rawExecute('COMMIT');
+ self::rawExecute('SET AUTOCOMMIT = 1');
+ self::$inTransaction = false;
+ }
+
+ public static function rollback()
+ {
+ self::rawExecute('ROLLBACK');
+ self::rawExecute('SET AUTOCOMMIT = 1');
+ self::$inTransaction = false;
+ }
+
+ public static function runTransactionV($callback, array $args)
+ {
+ self::startTransaction();
+ try {
+ if (call_user_func_array($callback, $args)) {
+ self::commit();
+ return true;
+ } else {
+ self::rollback();
+ return false;
+ }
+ } catch (Exception $e) {
+ self::rollback();
+ throw $e;
+ }
+ }
+
+ /** This function takes a callback followed by the arguments to be passed to the callback
+ * as arguments. It starts a transaction and execute the callback. If the callback fails
+ * (return false or raise an exception), the transaction is rollbacked, if the callback
+ * succeeds (return true), the transaction is committed.
+ */
+ public static function runTransaction()
+ {
+ $args = func_get_args();
+ $cb = array_shift($args);
+ return self::runTransactionV($cb, $args);
+ }
+
+ public static function iterator()
+ {
+ return new XDBIterator(self::prepare(func_get_args()));
+ }
+
+ public static function rawIterator($query)
+ {
+ return new XDBIterator($query);
+ }
+
+ public static function iterRow()
+ {
+ return new XDBIterator(self::prepare(func_get_args()), MYSQL_NUM);
+ }
+
+ public static function rawIterRow($query)
+ {
+ return new XDBIterator($query, MYSQL_NUM);
+ }
+
+ private static function findQuery($params, $default = array())
+ {
+ for ($i = 0 ; $i < count($default) ; ++$i) {
+ $is_query = false;
+ foreach (array('insert', 'select', 'replace', 'delete', 'update') as $kwd) {
+ if (stripos($params[0], $kwd) !== false) {
+ $is_query = true;
+ break;
+ }
+ }
+ if ($is_query) {
+ break;
+ } else {
+ $default[$i] = array_shift($params);
+ }
+ }
+ return array($default, $params);
+ }
+
+ /** Fetch all rows returned by the given query.
+ * This functions can take 2 optional arguments (cf XDBResult::fetchAllRow()).
+ * Optional arguments are given *before* the query.
+ */
+ public static function fetchAllRow()
+ {
+ list($args, $query) = self::findQuery(func_get_args(), array(false, false));
+ return self::queryv($query)->fetchAllRow($args[0], $args[1]);
+ }
+
+ public static function rawFetchAllRow($query, $id = false, $keep_array = false)
+ {
+ return self::rawQuery($query)->fetchAllRow($id, $keep_array);
+ }
+
+ /** Fetch all rows returned by the given query.
+ * This functions can take 2 optional arguments (cf XDBResult::fetchAllAssoc()).
+ * Optional arguments are given *before* the query.
+ */
+ public static function fetchAllAssoc()
+ {
+ list($args, $query) = self::findQuery(func_get_args(), array(false, false));
+ return self::queryv($query)->fetchAllAssoc($args[0], $args[1]);
+ }
+
+ public static function rawFetchAllAssoc($query, $id = false, $keep_array = false)
+ {
+ return self::rawQuery($query)->fetchAllAssoc($id, $keep_array);
+ }
+
+ public static function fetchOneCell()
+ {
+ list($args, $query) = self::findQuery(func_get_args());
+ return self::queryv($query)->fetchOneCell();
+ }