}
}
- }
- class Min_Driver extends Min_SQL {
- public $primary = "_id";
-
- function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
- $select = ($select == array("*")
- ? array()
- : array_fill_keys($select, true)
- );
- $sort = array();
- foreach ($order as $val) {
- $val = preg_replace('~ DESC$~', '', $val, 1, $count);
- $sort[$val] = ($count ? -1 : 1);
- }
- return new Min_Result($this->_conn->_db->selectCollection($table)
- ->find(array(), $select)
- ->sort($sort)
- ->limit($limit != "" ? +$limit : 0)
- ->skip($page * $limit)
- );
+ class Min_Driver extends Min_SQL {
+ public $primary = "_id";
+
+ function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
+ $select = ($select == array("*")
+ ? array()
+ : array_fill_keys($select, true)
+ );
+ $sort = array();
+ foreach ($order as $val) {
+ $val = preg_replace('~ DESC$~', '', $val, 1, $count);
+ $sort[$val] = ($count ? -1 : 1);
+ }
+ return new Min_Result($this->_conn->_db->selectCollection($table)
+ ->find(array(), $select)
+ ->sort($sort)
+ ->limit($limit != "" ? +$limit : 0)
+ ->skip($page * $limit)
+ );
+ }
+
+ function insert($table, $set) {
+ try {
+ $return = $this->_conn->_db->selectCollection($table)->insert($set);
+ $this->_conn->errno = $return['code'];
+ $this->_conn->error = $return['err'];
+ $this->_conn->last_id = $set['_id'];
+ return !$return['err'];
+ } catch (Exception $ex) {
+ $this->_conn->error = $ex->getMessage();
+ return false;
+ }
+ }
+ }
+
+ function get_databases($flush) {
+ global $connection;
+ $return = array();
+ $dbs = $connection->_link->listDBs();
+ foreach ($dbs['databases'] as $db) {
+ $return[] = $db['name'];
+ }
+ return $return;
+ }
+
+ function count_tables($databases) {
+ global $connection;
+ $return = array();
+ foreach ($databases as $db) {
+ $return[$db] = count($connection->_link->selectDB($db)->getCollectionNames(true));
+ }
+ return $return;
+ }
+
+ function tables_list() {
+ global $connection;
+ return array_fill_keys($connection->_db->getCollectionNames(true), 'table');
+ }
+
+ function drop_databases($databases) {
+ global $connection;
+ foreach ($databases as $db) {
+ $response = $connection->_link->selectDB($db)->drop();
+ if (!$response['ok']) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function indexes($table, $connection2 = null) {
+ global $connection;
+ $return = array();
+ foreach ($connection->_db->selectCollection($table)->getIndexInfo() as $index) {
+ $descs = array();
+ foreach ($index["key"] as $column => $type) {
+ $descs[] = ($type == -1 ? '1' : null);
+ }
+ $return[$index["name"]] = array(
+ "type" => ($index["name"] == "_id_" ? "PRIMARY" : ($index["unique"] ? "UNIQUE" : "INDEX")),
+ "columns" => array_keys($index["key"]),
+ "lengths" => array(),
+ "descs" => $descs,
+ );
+ }
+ return $return;
+ }
+
+ function fields($table) {
+ return fields_from_edit();
+ }
+
+ function found_rows($table_status, $where) {
+ global $connection;
+ //! don't call count_rows()
+ return $connection->_db->selectCollection($_GET["select"])->count($where);
}
-
- function insert($table, $set) {
- try {
- $return = $this->_conn->_db->selectCollection($table)->insert($set);
- $this->_conn->errno = $return['code'];
- $this->_conn->error = $return['err'];
- $this->_conn->last_id = $set['_id'];
- return !$return['err'];
- } catch (Exception $ex) {
- $this->_conn->error = $ex->getMessage();
+
+ $operators = array("=");
+
+ } elseif (class_exists('MongoDB\Driver\Manager')) {
+ class Min_DB {
+ var $extension = "MongoDB", $error, $last_id;
+ /** @var MongoDB\Driver\Manager */
+ var $_link;
+ var $_db, $_db_name;
+
+ function connect($server, $username, $password) {
+ global $adminer;
+ $db = $adminer->database();
+ $options = array();
+ if ($username != "") {
+ $options["username"] = $username;
+ $options["password"] = $password;
+ }
+ if ($db != "") {
+ $options["db"] = $db;
+ }
+ try {
+ $this->_link = new MongoDB\Driver\Manager("mongodb://$server", $options);
+ return true;
+ } catch (Exception $ex) {
+ $this->error = $ex->getMessage();
+ return false;
+ }
+ }
+
+ function query($query) {
return false;
}
+
+ function select_db($database) {
+ try {
+ $this->_db_name = $database;
+ return true;
+ } catch (Exception $ex) {
+ $this->error = $ex->getMessage();
+ return false;
+ }
+ }
+
+ function quote($string) {
+ return $string;
+ }
+
}
- }
+ class Min_Result {
+ var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
+
+ function __construct($result) {
+ foreach ($result as $item) {
+ $row = array();
+ foreach ($item as $key => $val) {
+ if (is_a($val, 'MongoDB\BSON\Binary')) {
+ $this->_charset[$key] = 63;
+ }
+ $row[$key] =
+ (is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . strval($val) . '")' :
+ (is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
+ (is_a($val, 'MongoDB\BSON\Binary') ? $val->bin : //! allow downloading
+ (is_a($val, 'MongoDB\BSON\Regex') ? strval($val) :
+ (is_object($val) ? json_encode($val, JSON_UNESCAPED_UNICODE) :
+ $val // MongoMinKey, MongoMaxKey
+ )))));
+ }
+ $this->_rows[] = $row;
+ foreach ($row as $key => $val) {
+ if (!isset($this->_rows[0][$key])) {
+ $this->_rows[0][$key] = null;
+ }
+ }
+ }
+ $this->num_rows = $result->count;
+ }
+
+ function fetch_assoc() {
+ $row = current($this->_rows);
+ if (!$row) {
+ return $row;
+ }
+ $return = array();
+ foreach ($this->_rows[0] as $key => $val) {
+ $return[$key] = $row[$key];
+ }
+ next($this->_rows);
+ return $return;
+ }
+ function fetch_row() {
+ $return = $this->fetch_assoc();
+ if (!$return) {
+ return $return;
+ }
+ return array_values($return);
+ }
+
+ function fetch_field() {
+ $keys = array_keys($this->_rows[0]);
+ $name = $keys[$this->_offset++];
+ return (object) array(
+ 'name' => $name,
+ 'charsetnr' => $this->_charset[$name],
+ );
+ }
- function connect() {
- global $adminer;
- $connection = new Min_DB;
- $credentials = $adminer->credentials();
- if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
- return $connection;
}
- return $connection->error;
- }
- function error() {
- global $connection;
- return h($connection->error);
- }
- function logged_user() {
- global $adminer;
- $credentials = $adminer->credentials();
- return $credentials[1];
- }
+ class Min_Driver extends Min_SQL {
+ public $primary = "_id";
- function get_databases($flush) {
- global $connection;
- $return = array();
- $dbs = $connection->_link->listDBs();
- foreach ($dbs['databases'] as $db) {
- $return[] = $db['name'];
+ function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
+ global $connection;
+ $select = ($select == array("*")
+ ? array()
+ : array_fill_keys($select, 1)
+ );
+ if (count($select) && !isset($select['_id'])) {
+ $select['_id'] = 0;
+ }
+ $where = where_to_query($where);
+ $sort = array();
+ foreach ($order as $val) {
+ $val = preg_replace('~ DESC$~', '', $val, 1, $count);
+ $sort[$val] = ($count ? -1 : 1);
+ }
+ if (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] > 0) {
+ $limit = $_GET['limit'];
+ }
+ $limit = min(200, max(1, (int)$limit));
+ $skip = $page * $limit;
+ $query = new MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort));
+ $results = $connection->_link->executeQuery("{$connection->_db_name}.$table", $query);
+ return new Min_Result($results);
+ }
+
+ function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
+ global $connection;
+ $db = $connection->_db_name;
+ $where = sql_query_where_parser($queryWhere);
+ $bulk = new MongoDB\Driver\BulkWrite(array());
+ if (isset($set['_id'])) {
+ unset($set['_id']);
+ }
+ $removeFields = array();
+ foreach ($set as $key => $value) {
+ if ($value == 'NULL') {
+ $removeFields[$key] = 1;
+ unset($set[$key]);
+ }
+ }
+ $update = array('$set' => $set);
+ if (count($removeFields)) {
+ $update['$unset'] = $removeFields;
+ }
+ $bulk->update($where, $update, array('upsert' => false));
+ $results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
+ $connection->affected_rows = $results->getModifiedCount();
+ return true;
+ }
+
+ function delete($table, $queryWhere, $limit = 0) {
+ global $connection;
+ $db = $connection->_db_name;
+ $where = sql_query_where_parser($queryWhere);
+ $bulk = new MongoDB\Driver\BulkWrite(array());
+ $bulk->delete($where, array('limit' => $limit));
+ $results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
+ $connection->affected_rows = $results->getDeletedCount();
+ return true;
+ }
+
+ function insert($table, $set) {
+ global $connection;
+ $db = $connection->_db_name;
+ $bulk = new MongoDB\Driver\BulkWrite(array());
+ if (isset($set['_id']) && empty($set['_id'])) {
+ unset($set['_id']);
+ }
+ $bulk->insert($set);
+ $results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
+ $connection->affected_rows = $results->getInsertedCount();
+ return true;
+ }
}
- return $return;
- }
- function collations() {
- return array();
- }
+ function get_databases($flush) {
+ /** @var $connection Min_DB */
+ global $connection;
+ $return = array();
+ $command = new MongoDB\Driver\Command(array('listDatabases' => 1));
+ $results = $connection->_link->executeCommand('admin', $command);
+ foreach ($results as $dbs) {
+ foreach ($dbs->databases as $db) {
+ $return[] = $db->name;
+ }
+ }
+ return $return;
+ }
- function db_collation($db, $collations) {
- }
+ function count_tables($databases) {
+ $return = array();
+ return $return;
+ }
- function count_tables($databases) {
- global $connection;
- $return = array();
- foreach ($databases as $db) {
- $return[$db] = count($connection->_link->selectDB($db)->getCollectionNames(true));
+ function tables_list() {
+ global $connection;
+ $command = new MongoDB\Driver\Command(array('listCollections' => 1));
+ $results = $connection->_link->executeCommand($connection->_db_name, $command);
+ $collections = array();
+ foreach ($results as $result) {
+ $collections[$result->name] = 'table';
+ }
+ return $collections;
}
- return $return;
+
+ function drop_databases($databases) {
+ return false;
+ }
+
+ function indexes($table, $connection2 = null) {
+ global $connection;
+ $return = array();
+ $command = new MongoDB\Driver\Command(array('listIndexes' => $table));
+ $results = $connection->_link->executeCommand($connection->_db_name, $command);
+ foreach ($results as $index) {
+ $descs = array();
+ $columns = array();
+ foreach (get_object_vars($index->key) as $column => $type) {
+ $descs[] = ($type == -1 ? '1' : null);
+ $columns[] = $column;
+ }
+ $return[$index->name] = array(
+ "type" => ($index->name == "_id_" ? "PRIMARY" : (isset($index->unique) ? "UNIQUE" : "INDEX")),
+ "columns" => $columns,
+ "lengths" => array(),
+ "descs" => $descs,
+ );
+ }
+ return $return;
+ }
+
+ function fields($table) {
+ $fields = fields_from_edit();
+ if (!count($fields)) {
+ global $driver;
+ $result = $driver->select($table, array("*"), null, null, array(), 10);
+ while ($row = $result->fetch_assoc()) {
+ foreach ($row as $key => $val) {
+ $row[$key] = null;
+ $fields[$key] = array(
+ "field" => $key,
+ "type" => "string",
+ "null" => ($key != $driver->primary),
+ "auto_increment" => ($key == $driver->primary),
+ "privileges" => array(
+ "insert" => 1,
+ "select" => 1,
+ "update" => 1,
+ ),
+ );
+ }
+ }
+ }
+ return $fields;
+ }
+
+ function found_rows($table_status, $where) {
+ global $connection;
+ $where = where_to_query($where);
+ $command = new MongoDB\Driver\Command(array('count' => $table_status['Name'], 'query' => $where));
+ $results = $connection->_link->executeCommand($connection->_db_name, $command);
+ $toArray = $results->toArray();
+ return $toArray[0]->n;
+ }
+
+ function sql_query_where_parser($queryWhere) {
+ $queryWhere = trim(preg_replace('/WHERE[\s]?[(]?\(?/', '', $queryWhere));
+ $queryWhere = preg_replace('/\)\)\)$/', ')', $queryWhere);
+ $wheres = explode(' AND ', $queryWhere);
+ $wheresOr = explode(') OR (', $queryWhere);
+ $where = array();
+ foreach ($wheres as $whereStr) {
+ $where[] = trim($whereStr);
+ }
+ if (count($wheresOr) == 1) {
+ $wheresOr = array();
+ } elseif (count($wheresOr) > 1) {
+ $where = array();
+ }
+ return where_to_query($where, $wheresOr);
+ }
+
+ function where_to_query($whereAnd = array(), $whereOr = array()) {
+ global $operators;
+ $data = array();
+ foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
+ if (is_array($where)) {
+ foreach ($where as $expression) {
+ list($col, $op, $val) = explode(" ", $expression, 3);
+ if ($col == "_id") {
+ $val = str_replace('MongoDB\BSON\ObjectID("', "", $val);
+ $val = str_replace('")', "", $val);
+ $val = new MongoDB\BSON\ObjectID($val);
+ }
+ if (!in_array($op, $operators)) {
+ continue;
+ }
+ switch ($op) {
+ case '=':
+ $op = '$eq';
+ break;
+ case '!=':
+ $op = '$ne';
+ break;
+ case '>':
+ $op = '$gt';
+ break;
+ case '<':
+ $op = '$lt';
+ break;
+ case '>=':
+ $op = '$gte';
+ break;
+ case '<=':
+ $op = '$lte';
+ break;
+ case 'regex':
+ $op = '$regex';
+ break;
+ case '(f)=':
+ $op = '$eq';
+ $val = (float)$val;
+ break;
+ case '(f)!=':
+ $op = '$ne';
+ $val = (float)$val;
+ break;
+ case '(f)>':
+ $op = '$gt';
+ $val = (float)$val;
+ break;
+ case '(f)<':
+ $op = '$lt';
+ $val = (float)$val;
+ break;
+ case '(f)>=':
+ $op = '$gte';
+ $val = (float)$val;
+ break;
+ case '(f)<=':
+ $op = '$lte';
+ $val = (float)$val;
+ break;
+ case '(date)=':
+ $op = '$eq';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ case '(date)!=':
+ $op = '$ne';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ case '(date)>':
+ $op = '$gt';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ case '(date)<':
+ $op = '$lt';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ case '(date)>=':
+ $op = '$gte';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ case '(date)<=':
+ $op = '$lte';
+ $dateTime = (new \DateTime($val));
+ $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
+ break;
+ default:
+ continue;
+ }
+ if ($type == 'and') {
+ $data['$and'][] = array($col => array($op => $val));
+ } elseif ($type == 'or') {
+ $data['$or'][] = array($col => array($op => $val));
+ }
+ }
+ }
+ }
+ return $data;
+ }
+
+ $operators = array(
+ "=",
+ "!=",
+ ">",
+ "<",
+ ">=",
+ "<=",
+ "regex",
+ "(f)=",
+ "(f)!=",
+ "(f)>",
+ "(f)<",
+ "(f)>=",
+ "(f)<=",
+ "(date)=",
+ "(date)!=",
+ "(date)>",
+ "(date)<",
+ "(date)>=",
+ "(date)<=",
+ );
}
- function tables_list() {
- global $connection;
- return array_fill_keys($connection->_db->getCollectionNames(true), 'table');
+ function table($idf) {
+ return $idf;
+ }
+
+ function idf_escape($idf) {
+ return $idf;
}
function table_status($name = "", $fast = false) {
return $return;
}
- function information_schema() {
+ function last_id() {
+ global $connection;
+ return $connection->last_id;
}
- function is_view($table_status) {
+ function error() {
+ global $connection;
+ return h($connection->error);
+ }
+
+ function collations() {
+ return array();
+ }
+
+ function logged_user() {
+ global $adminer;
+ $credentials = $adminer->credentials();
+ return $credentials[1];
+ }
+
+ function connect() {
+ global $adminer;
+ $connection = new Min_DB;
+ $credentials = $adminer->credentials();
+ if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
+ return $connection;
+ }
+ return $connection->error;
}
- function drop_databases($databases) {
+ function alter_indexes($table, $alter) {
global $connection;
- foreach ($databases as $db) {
- $response = $connection->_link->selectDB($db)->drop();
- if (!$response['ok']) {
+ foreach ($alter as $val) {
+ list($type, $name, $set) = $val;
+ if ($set == "DROP") {
+ $return = $connection->_db->command(array("deleteIndexes" => $table, "index" => $name));
+ } else {
+ $columns = array();
+ foreach ($set as $column) {
+ $column = preg_replace('~ DESC$~', '', $column, 1, $count);
+ $columns[$column] = ($count ? -1 : 1);
+ }
+ $return = $connection->_db->selectCollection($table)->ensureIndex($columns, array(
+ "unique" => ($type == "UNIQUE"),
+ "name" => $name,
+ //! "sparse"
+ ));
+ }
+ if ($return['errmsg']) {
+ $connection->error = $return['errmsg'];
return false;
}
}
return true;
}
- function indexes($table, $connection2 = null) {
- global $connection;
- $return = array();
- foreach ($connection->_db->selectCollection($table)->getIndexInfo() as $index) {
- $descs = array();
- foreach ($index["key"] as $column => $type) {
- $descs[] = ($type == -1 ? '1' : null);
- }
- $return[$index["name"]] = array(
- "type" => ($index["name"] == "_id_" ? "PRIMARY" : ($index["unique"] ? "UNIQUE" : "INDEX")),
- "columns" => array_keys($index["key"]),
- "lengths" => array(),
- "descs" => $descs,
- );
- }
- return $return;
+ function support($feature) {
+ return preg_match("~database|indexes~", $feature);
}
- function fields($table) {
- return fields_from_edit();
+ function db_collation($db, $collations) {
+ }
+
+ function information_schema() {
+ }
+
+ function is_view($table_status) {
}
function convert_field($field) {
return array();
}
- function found_rows($table_status, $where) {
- global $connection;
- //! don't call count_rows()
- return $connection->_db->selectCollection($_GET["select"])->count($where);
- }
-
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
if ($table == "") {
return true;
}
- function alter_indexes($table, $alter) {
- global $connection;
- foreach ($alter as $val) {
- list($type, $name, $set) = $val;
- if ($set == "DROP") {
- $return = $connection->_db->command(array("deleteIndexes" => $table, "index" => $name));
- } else {
- $columns = array();
- foreach ($set as $column) {
- $column = preg_replace('~ DESC$~', '', $column, 1, $count);
- $columns[$column] = ($count ? -1 : 1);
- }
- $return = $connection->_db->selectCollection($table)->ensureIndex($columns, array(
- "unique" => ($type == "UNIQUE"),
- "name" => $name,
- //! "sparse"
- ));
- }
- if ($return['errmsg']) {
- $connection->error = $return['errmsg'];
- return false;
- }
- }
- return true;
- }
-
- function last_id() {
- global $connection;
- return $connection->last_id;
- }
-
- function table($idf) {
- return $idf;
- }
-
- function idf_escape($idf) {
- return $idf;
- }
-
- function support($feature) {
- return preg_match("~database|indexes~", $feature);
- }
-
$jush = "mongo";
- $operators = array("=");
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));