encode($inData) . ' */'; } function error($inMessage) { $inMessage = str_replace('"', '\\"', $inMessage); error_log($inMessage); //echo '/* ({error: true, message: "' . $inMessage . '"}) */'; echoJson(array('error' => true, 'message' => $inMessage)); exit; } function getArray($inResult, $inArray="true") { $o = Array(); while ($row = ($inArray ? mysql_fetch_row($inResult) : mysql_fetch_object($inResult))) $o[] = $row; return $o; } // connect to DB mysql_connect($dbserver, $dbuser, $dbpassword); // select DB $database = getPostString("database"); $database = ($database ? $database : $db); if (!mysql_select_db($database)) error('failed to select db: ' . mysql_error()); // select table $table = getPostString("table"); $table = ($table ? $table : $dbtable); // cache $colCache = NULL; $pkCache = NULL; // set UTF8 output (MySql > 4.0) mysql_query("SET NAMES UTF8"); // server, database, table meta data function getDatabases() { $result = mysql_query("SHOW DATABASES"); $output = Array(); while ($row = mysql_fetch_row($result)) { $r = strtolower($row[0]); if ($r != 'mysql' && $r != 'information_schema') $output[] = $row[0]; } return $output; } function getTables() { global $database; $result = mysql_query("SHOW TABLES FROM $database"); $output = Array(); while ($row = mysql_fetch_row($result)) $output[] = $row[0]; return $output; } function getColumns() { global $table, $colCache; if (!$colCache) { $result = mysql_query("SHOW COLUMNS FROM `$table`"); return getArray($result, false); $colCache = getArray($result, false); } return $colCache; } // returns object: $this->name, $this->index function getPk() { global $pkCache; if (!$pkCache) { $k = ''; $columns = getColumns(); for ($i=0; $i < count($columns); $i++) { $c = $columns[$i]; if ($c->Key == 'PRI') { $k = $c->Field; break; } } $pkCache->index = $i; $pkCache->name = $k; } return $pkCache; } function getTableInfo() { global $table, $database; $c = getColumns(); $r = rowcount(); return array("count" => $r, "columns" => $c, "database" => $database, "table" => $table); } function getOldPostPkValue() { $pk = getPk(); return getPostString('_o' . $pk->index); } function getNewPostPkValue() { $pk = getPk(); return getPostString('_' . $pk->index); } function getPostColumns() { $columns = getColumns(); for ($i=0, $a=array(), $p; (($p=getPostString("_".$i)) != ''); $i++) { $r = new stdClass(); $r->name = $columns[$i]->Field; $r->value = $p; $a[] = $r; } return $a; } function getOrderBy() { $ob = getPostString("orderby"); if (is_numeric($ob)) { $columns = getColumns(); $ob = $columns[intval($ob)-1]->Field; } return $ob; } function getWhere() { $w = getPostString("where"); return ($w ? " WHERE $w" : ""); } // basic operations function rowcount() { global $table; $query = "SELECT COUNT(*) FROM `$table`" . getWhere(); $result = mysql_query($query); if (!$result) error("failed to perform query: $query. " . mysql_error()); if ($row = mysql_fetch_row($result)) return $row[0]; else return 0; } function select($inQuery = '') { global $table; // built limit clause $lim = (int)getPostString("limit"); $off = (int)getPostString("offset"); $limit = ($lim || $off ? " LIMIT $off, $lim" : ""); // build order by clause $desc = (boolean)getPostString("desc"); $ob = getOrderBy(); $orderby = ($ob ? " ORDER BY `" . $ob . "`" . ($desc ? " DESC" : "") : ""); // build query $query = ($inQuery ? $inQuery : "SELECT * FROM `$table`" . getWhere() . $orderby . $limit); // execute query if (!$result = mysql_query($query)) error("failed to perform query: $query. " . mysql_error()); // fetch each result row return getArray($result); } function reflectRow() { global $table; $pk = getPk(); $key = getNewPostPkValue(); $where = "`$pk->name`=\"$key\""; return select("SELECT * FROM `$table` WHERE $where LIMIT 1"); } function update() { // build set clause for ($i=0, $set = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++) $set[] = "`$v->name` = '$v->value'"; $set = implode(', ', $set); // our table global $table; // build query $pk = getPk(); $pkValue = getOldPostPkValue(); $query = "UPDATE `$table` SET $set WHERE `$pk->name` = '$pkValue' LIMIT 1"; // execute query if (!mysql_query($query)) error("failed to perform query: [$query]. " . "MySql says: [" . mysql_error() ."]"); else { return reflectRow(); } } function insert() { global $table; // build values clause for ($i=0, $values = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++) $values[] = $v->value; $values = '"' . implode('", "', $values) . '"'; // build query $query = "INSERT INTO `$table` VALUES($values)"; // execute query if (!mysql_query($query)) error("failed to perform query: [$query]. " . "MySql says: [" . mysql_error() ."]"); else { return reflectRow(); } } function delete() { global $table; // build query $n = getPostString("count"); $pk = getPk(); for ($i = 0, $deleted=array(); $i < $n; $i++) { $key = getPostString("_$i"); array_push($deleted, $key); $query = "DELETE FROM `$table` WHERE `$pk->name`=\"$key\" LIMIT 1"; // execute query if (!mysql_query($query) || mysql_affected_rows() != 1) error("failed to perform query: [$query]. " . "Affected rows: " . mysql_affected_rows() .". " . "MySql says: [" . mysql_error() ."]"); } return $deleted; } // find (full text search) function findData($inFindCol, $inFind, $inOrderBy, $inFullText) { global $table; $where = ($inFullText ? "WHERE MATCH(`$inFindCol`) AGAINST ('$inFind')" : "WHERE $inFindCol LIKE '$inFind'"); $query = "SELECT * FROM $table $where $inOrderBy"; $result = mysql_query($query); // return rows return getArray($result); } // binary search through sorted data, supports start point ($inFindFrom) and direction ($inFindForward) function findRow($inData, $inFindFrom=-1, $inFindForward) { $b = -1; $l = count($inData); if (!$inData) return $b; if (!$inFindFrom==-1 || $l < 2) $b = 0; else { // binary search $t = $l-1; $b = 0; while ($b <= $t) { $p = floor(($b+$t)/2); $d = $inData[$p][0]; if ($d < $inFindFrom) $b = $p + 1; else if ($d > $inFindFrom) $t = $p - 1; else { $b = $p; break; } } if ($inFindFrom == $inData[$b][0]) { // add or subtract 1 $b = ($inFindForward ? ($b+1 > $l-1 ? 0 : $b+1) : ($b-1 < 0 ? $l-1 : $b-1) ); } else if (!$inFindForward) // subtract 1 $b = ($b-1 < 0 ? $l-1 : $b-1); } return $inData[$b][0]; } function buildFindWhere($inFindData, $inKey, $inCol) { $o = Array(); foreach($inFindData as $row) $o[] = $inCol . "='" . $row[$inKey] . "'"; return (count($o) ? ' WHERE ' . implode(' OR ', $o) : ''); } function find($inFindCol, $inFind='', $inOb='', $inFindFrom=0, $inFindForward=true, $inFullText=true) { global $table; // build order by clause $desc = (boolean)getPostString("desc"); if (!$inOb) $inOb = getOrderBy(); if ($inOb) $inOb = "`" . $inOb . "`" ; $orderby = ($inOb ? " ORDER BY $inOb " . ($desc ? " DESC" : "") : ""); // update inputs from post if (!$inFind) $inFind = getPostString('findText'); if (!$inFindCol) $inFindCol = getPostString('findCol'); if (empty($inFindFrom)) $inFindFrom = getPostString('findFrom'); $ff = getPostString('findForward'); if ($ff) $inFindForward = (strtolower($ff) == 'true' ? true : false); $ft = getPostString('findFullText'); if ($ft) $inFullText = (strtolower($ft) == 'true' ? true : false); // get find data $f = findData($inFindCol, $inFind, $orderby, $inFullText); $pk = getPk(); // execute query $where = buildFindWhere($f, $pk->index, 'f'); $query = "SELECT Row, f FROM (SELECT @row := @row + 1 AS Row, $pk->name as f FROM `$table` $orderby) AS tempTable $where"; mysql_query('SET @row = -1;'); if (!$result = mysql_query($query)) error("failed to perform query: $query. " . mysql_error()); // return row number return findRow(getArray($result), $inFindFrom, $inFindForward); } // our command list $cmds = array( "count" => "rowcount", "select" => "select", "update" => "update", "insert" => "insert", "delete" => "delete", "find" => "find", "databases" => "getDatabases", "tables" => "getTables", "columns" => "getColumns", "info" => "getTableInfo" ); // process input params $cmd = @$_POST["command"]; //$cmd="select"; // dispatch command $func = @$cmds[$cmd]; if (function_exists($func)) echoJson(call_user_func($func)); else error("bad command"); ?>