5390a287bb2999faf1eb4c9cdf93fa6190e73e46.svn-base 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <?php
  2. // db settings
  3. $dbserver = 'localhost';
  4. $dbuser = 'root';
  5. $dbpassword = 'root';
  6. error_reporting(E_ALL);
  7. /*
  8. Simple protocol:
  9. - Inputs via POST variables.
  10. - Output is a string that can be evaluated into a JSON
  11. First element of the array contains return status.
  12. This simplified tutorial code should not be deployed without a security review.
  13. */
  14. @include "json.php";
  15. // set up response encoding
  16. header("Content-Type: text/html; charset=utf-8");
  17. // util
  18. function getPostString($inName) {
  19. // make sure input strings are 'clean'
  20. return mysql_real_escape_string(@$_POST[$inName]);
  21. }
  22. // used for json encoding
  23. $json = new Services_JSON();
  24. function echoJson($inData) {
  25. global $json;
  26. // delay in ms
  27. $delay = getPostString('delay');
  28. if (!empty($delay))
  29. usleep($delay * 1000);
  30. echo '/* ' . $json->encode($inData) . ' */';
  31. }
  32. function error($inMessage) {
  33. $inMessage = str_replace('"', '\\"', $inMessage);
  34. error_log($inMessage);
  35. //echo '/* ({error: true, message: "' . $inMessage . '"}) */';
  36. echoJson(array('error' => true, 'message' => $inMessage));
  37. exit;
  38. }
  39. function getArray($inResult, $inArray="true") {
  40. $o = Array();
  41. while ($row = ($inArray ? mysql_fetch_row($inResult) : mysql_fetch_object($inResult)))
  42. $o[] = $row;
  43. return $o;
  44. }
  45. // connect to DB
  46. mysql_connect($dbserver, $dbuser, $dbpassword);
  47. // select DB
  48. $database = getPostString("database");
  49. $database = ($database ? $database : $db);
  50. if (!mysql_select_db($database))
  51. error('failed to select db: ' . mysql_error());
  52. // select table
  53. $table = getPostString("table");
  54. $table = ($table ? $table : $dbtable);
  55. // cache
  56. $colCache = NULL;
  57. $pkCache = NULL;
  58. // set UTF8 output (MySql > 4.0)
  59. mysql_query("SET NAMES UTF8");
  60. // server, database, table meta data
  61. function getDatabases() {
  62. $result = mysql_query("SHOW DATABASES");
  63. $output = Array();
  64. while ($row = mysql_fetch_row($result)) {
  65. $r = strtolower($row[0]);
  66. if ($r != 'mysql' && $r != 'information_schema')
  67. $output[] = $row[0];
  68. }
  69. return $output;
  70. }
  71. function getTables() {
  72. global $database;
  73. $result = mysql_query("SHOW TABLES FROM $database");
  74. $output = Array();
  75. while ($row = mysql_fetch_row($result))
  76. $output[] = $row[0];
  77. return $output;
  78. }
  79. function getColumns() {
  80. global $table, $colCache;
  81. if (!$colCache) {
  82. $result = mysql_query("SHOW COLUMNS FROM `$table`");
  83. return getArray($result, false);
  84. $colCache = getArray($result, false);
  85. }
  86. return $colCache;
  87. }
  88. // returns object: $this->name, $this->index
  89. function getPk() {
  90. global $pkCache;
  91. if (!$pkCache) {
  92. $k = '';
  93. $columns = getColumns();
  94. for ($i=0; $i < count($columns); $i++) {
  95. $c = $columns[$i];
  96. if ($c->Key == 'PRI') {
  97. $k = $c->Field;
  98. break;
  99. }
  100. }
  101. $pkCache->index = $i;
  102. $pkCache->name = $k;
  103. }
  104. return $pkCache;
  105. }
  106. function getTableInfo() {
  107. global $table, $database;
  108. $c = getColumns();
  109. $r = rowcount();
  110. return array("count" => $r, "columns" => $c, "database" => $database, "table" => $table);
  111. }
  112. function getOldPostPkValue() {
  113. $pk = getPk();
  114. return getPostString('_o' . $pk->index);
  115. }
  116. function getNewPostPkValue() {
  117. $pk = getPk();
  118. return getPostString('_' . $pk->index);
  119. }
  120. function getPostColumns() {
  121. $columns = getColumns();
  122. for ($i=0, $a=array(), $p; (($p=getPostString("_".$i)) != ''); $i++) {
  123. $r = new stdClass();
  124. $r->name = $columns[$i]->Field;
  125. $r->value = $p;
  126. $a[] = $r;
  127. }
  128. return $a;
  129. }
  130. function getOrderBy() {
  131. $ob = getPostString("orderby");
  132. if (is_numeric($ob)) {
  133. $columns = getColumns();
  134. $ob = $columns[intval($ob)-1]->Field;
  135. }
  136. return $ob;
  137. }
  138. function getWhere() {
  139. $w = getPostString("where");
  140. return ($w ? " WHERE $w" : "");
  141. }
  142. // basic operations
  143. function rowcount() {
  144. global $table;
  145. $query = "SELECT COUNT(*) FROM `$table`" . getWhere();
  146. $result = mysql_query($query);
  147. if (!$result)
  148. error("failed to perform query: $query. " . mysql_error());
  149. if ($row = mysql_fetch_row($result))
  150. return $row[0];
  151. else
  152. return 0;
  153. }
  154. function select($inQuery = '') {
  155. global $table;
  156. // built limit clause
  157. $lim = (int)getPostString("limit");
  158. $off = (int)getPostString("offset");
  159. $limit = ($lim || $off ? " LIMIT $off, $lim" : "");
  160. // build order by clause
  161. $desc = (boolean)getPostString("desc");
  162. $ob = getOrderBy();
  163. $orderby = ($ob ? " ORDER BY `" . $ob . "`" . ($desc ? " DESC" : "") : "");
  164. // build query
  165. $query = ($inQuery ? $inQuery : "SELECT * FROM `$table`" . getWhere() . $orderby . $limit);
  166. // execute query
  167. if (!$result = mysql_query($query))
  168. error("failed to perform query: $query. " . mysql_error());
  169. // fetch each result row
  170. return getArray($result);
  171. }
  172. function reflectRow() {
  173. global $table;
  174. $pk = getPk();
  175. $key = getNewPostPkValue();
  176. $where = "`$pk->name`=\"$key\"";
  177. return select("SELECT * FROM `$table` WHERE $where LIMIT 1");
  178. }
  179. function update() {
  180. // build set clause
  181. for ($i=0, $set = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
  182. $set[] = "`$v->name` = '$v->value'";
  183. $set = implode(', ', $set);
  184. // our table
  185. global $table;
  186. // build query
  187. $pk = getPk();
  188. $pkValue = getOldPostPkValue();
  189. $query = "UPDATE `$table` SET $set WHERE `$pk->name` = '$pkValue' LIMIT 1";
  190. // execute query
  191. if (!mysql_query($query))
  192. error("failed to perform query: [$query]. " .
  193. "MySql says: [" . mysql_error() ."]");
  194. else {
  195. return reflectRow();
  196. }
  197. }
  198. function insert() {
  199. global $table;
  200. // build values clause
  201. for ($i=0, $values = array(), $cols = getPostColumns(), $v; ($v=$cols[$i]); $i++)
  202. $values[] = $v->value;
  203. $values = '"' . implode('", "', $values) . '"';
  204. // build query
  205. $query = "INSERT INTO `$table` VALUES($values)";
  206. // execute query
  207. if (!mysql_query($query))
  208. error("failed to perform query: [$query]. " .
  209. "MySql says: [" . mysql_error() ."]");
  210. else {
  211. return reflectRow();
  212. }
  213. }
  214. function delete() {
  215. global $table;
  216. // build query
  217. $n = getPostString("count");
  218. $pk = getPk();
  219. for ($i = 0, $deleted=array(); $i < $n; $i++) {
  220. $key = getPostString("_$i");
  221. array_push($deleted, $key);
  222. $query = "DELETE FROM `$table` WHERE `$pk->name`=\"$key\" LIMIT 1";
  223. // execute query
  224. if (!mysql_query($query) || mysql_affected_rows() != 1)
  225. error("failed to perform query: [$query]. " .
  226. "Affected rows: " . mysql_affected_rows() .". " .
  227. "MySql says: [" . mysql_error() ."]");
  228. }
  229. return $deleted;
  230. }
  231. // find (full text search)
  232. function findData($inFindCol, $inFind, $inOrderBy, $inFullText) {
  233. global $table;
  234. $where = ($inFullText ? "WHERE MATCH(`$inFindCol`) AGAINST ('$inFind')" : "WHERE $inFindCol LIKE '$inFind'");
  235. $query = "SELECT * FROM $table $where $inOrderBy";
  236. $result = mysql_query($query);
  237. // return rows
  238. return getArray($result);
  239. }
  240. // binary search through sorted data, supports start point ($inFindFrom) and direction ($inFindForward)
  241. function findRow($inData, $inFindFrom=-1, $inFindForward) {
  242. $b = -1;
  243. $l = count($inData);
  244. if (!$inData)
  245. return $b;
  246. if (!$inFindFrom==-1 || $l < 2)
  247. $b = 0;
  248. else {
  249. // binary search
  250. $t = $l-1;
  251. $b = 0;
  252. while ($b <= $t) {
  253. $p = floor(($b+$t)/2);
  254. $d = $inData[$p][0];
  255. if ($d < $inFindFrom)
  256. $b = $p + 1;
  257. else if ($d > $inFindFrom)
  258. $t = $p - 1;
  259. else {
  260. $b = $p;
  261. break;
  262. }
  263. }
  264. if ($inFindFrom == $inData[$b][0]) {
  265. // add or subtract 1
  266. $b = ($inFindForward ? ($b+1 > $l-1 ? 0 : $b+1) : ($b-1 < 0 ? $l-1 : $b-1) );
  267. }
  268. else if (!$inFindForward)
  269. // subtract 1
  270. $b = ($b-1 < 0 ? $l-1 : $b-1);
  271. }
  272. return $inData[$b][0];
  273. }
  274. function buildFindWhere($inFindData, $inKey, $inCol) {
  275. $o = Array();
  276. foreach($inFindData as $row)
  277. $o[] = $inCol . "='" . $row[$inKey] . "'";
  278. return (count($o) ? ' WHERE ' . implode(' OR ', $o) : '');
  279. }
  280. function find($inFindCol, $inFind='', $inOb='', $inFindFrom=0, $inFindForward=true, $inFullText=true) {
  281. global $table;
  282. // build order by clause
  283. $desc = (boolean)getPostString("desc");
  284. if (!$inOb)
  285. $inOb = getOrderBy();
  286. if ($inOb)
  287. $inOb = "`" . $inOb . "`" ;
  288. $orderby = ($inOb ? " ORDER BY $inOb " . ($desc ? " DESC" : "") : "");
  289. // update inputs from post
  290. if (!$inFind)
  291. $inFind = getPostString('findText');
  292. if (!$inFindCol)
  293. $inFindCol = getPostString('findCol');
  294. if (empty($inFindFrom))
  295. $inFindFrom = getPostString('findFrom');
  296. $ff = getPostString('findForward');
  297. if ($ff)
  298. $inFindForward = (strtolower($ff) == 'true' ? true : false);
  299. $ft = getPostString('findFullText');
  300. if ($ft)
  301. $inFullText = (strtolower($ft) == 'true' ? true : false);
  302. // get find data
  303. $f = findData($inFindCol, $inFind, $orderby, $inFullText);
  304. $pk = getPk();
  305. // execute query
  306. $where = buildFindWhere($f, $pk->index, 'f');
  307. $query = "SELECT Row, f FROM (SELECT @row := @row + 1 AS Row, $pk->name as f FROM `$table` $orderby) AS tempTable $where";
  308. mysql_query('SET @row = -1;');
  309. if (!$result = mysql_query($query))
  310. error("failed to perform query: $query. " . mysql_error());
  311. // return row number
  312. return findRow(getArray($result), $inFindFrom, $inFindForward);
  313. }
  314. // our command list
  315. $cmds = array(
  316. "count" => "rowcount",
  317. "select" => "select",
  318. "update" => "update",
  319. "insert" => "insert",
  320. "delete" => "delete",
  321. "find" => "find",
  322. "databases" => "getDatabases",
  323. "tables" => "getTables",
  324. "columns" => "getColumns",
  325. "info" => "getTableInfo"
  326. );
  327. // process input params
  328. $cmd = @$_POST["command"];
  329. //$cmd="select";
  330. // dispatch command
  331. $func = @$cmds[$cmd];
  332. if (function_exists($func))
  333. echoJson(call_user_func($func));
  334. else
  335. error("bad command");
  336. ?>