PageRenderTime 73ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/db/library/dbscript/mysql.php

https://github.com/tjgillies/openmicroblogger
PHP | 741 lines | 641 code | 63 blank | 37 comment | 142 complexity | 2405bb841c93806c9771e9076a135932 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * dbscript -- restful openid framework
  4. * @version 0.6.0 -- 22-October-2008
  5. * @author Brian Hendrickson <brian@dbscript.net>
  6. * @link http://dbscript.net/
  7. * @copyright Copyright 2009 Brian Hendrickson
  8. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  9. * @package dbscript
  10. */
  11. /**
  12. * MySQL
  13. *
  14. * adapter for the MySQL database system
  15. *
  16. * Usage:
  17. * <code>
  18. * $db = new MySQL ( 'hostname', 'database_name', 'username', 'password' );
  19. * </code>
  20. *
  21. * More info...
  22. * {@link http://dbscript.net/mysql}
  23. *
  24. * @package dbscript
  25. * @author Brian Hendrickson <brian@dbscript.net>
  26. * @access public
  27. * @version 0.6.0 -- 22-October-2008
  28. * @todo support array datatypes
  29. */
  30. class MySQL extends Database {
  31. var $host;
  32. var $user;
  33. var $pass;
  34. var $opt1;
  35. var $opt2;
  36. var $dbname;
  37. var $prefix;
  38. function MySQL() {
  39. global $prefix;
  40. $prefix = '';
  41. $this->prefix = $prefix;
  42. $this->db_open = false;
  43. $this->models = array();
  44. $this->recordsets = array();
  45. $this->max_blob_length = 6144000; // default max blob file size is 6MB
  46. $this->max_string_length = 1024000; // default max string length is 1MB
  47. $this->datatype_map = array(
  48. 'float' => 'float', // precise to 23 digits
  49. 'double' => 'float', // 24-53 digits
  50. 'decimal' => 'float', // double stored as string
  51. 'int' => 'int',
  52. 'tinyint' => 'int',
  53. 'smallint' => 'int',
  54. 'mediumint' => 'int',
  55. 'bigint' => 'int',
  56. 'char' => 'char',
  57. 'varchar' => 'char',
  58. 'tinytext' => 'char',
  59. 'text' => 'text',
  60. 'mediumtext' => 'text',
  61. 'longtext' => 'text',
  62. 'bigtext' => 'text',
  63. 'time' => 'time',
  64. 'timestamp' => 'time',
  65. 'datetime' => 'time',
  66. 'date' => 'date',
  67. 'boolean' => 'bool',
  68. 'bool' => 'bool',
  69. 'blob' => 'blob',
  70. 'mediumblob' => 'blob',
  71. 'longblob' => 'blob'
  72. );
  73. $args = func_get_args();
  74. $argnames = array('host','dbname','user','pass','opt1','opt2');
  75. for ($i = 0; $i < count($args); $i++) {
  76. $this->$argnames[$i] = $args[$i];
  77. }
  78. $this->true_values = array('t','true','1',true);
  79. $this->alias_array = array();
  80. $this->connect();
  81. }
  82. function connect() { /* function to re/establish the DB connection */
  83. trigger_before( 'connect', $this, $this );
  84. $this->conn = mysql_connect($this->host,$this->user,$this->pass,$this->opt1,$this->opt2);
  85. if (!$this->conn) {
  86. $this->db_open = false;
  87. trigger_error("Sorry, the database connection failed. Please check your database connection settings.".@mysql_error($this->conn), E_USER_ERROR );
  88. } else {
  89. $this->db_open = mysql_select_db($this->dbname);
  90. if (!$this->db_open)
  91. trigger_error(@mysql_error($this->conn), E_USER_ERROR );
  92. }
  93. return $this->db_open;
  94. }
  95. function escape_string( $string ) { /* watch for bad characters in each SQL query */
  96. trigger_before( 'escape_string', $this, $this );
  97. if (!(strlen($string) > 0)) { return $string; }
  98. $result = @mysql_escape_string($string);
  99. if (!$result && !(is_numeric($string))) {
  100. trigger_error("error in escape_string in mysql.php ".@mysql_error($this->conn), E_USER_ERROR );
  101. } else {
  102. return $result;
  103. }
  104. }
  105. function create_openid_tables() {
  106. if (in_array('oauth_consumers',$this->tables))
  107. return;
  108. $result = $this->get_result("CREATE TABLE openid_identities (
  109. uurl_id bigint(20) NOT NULL auto_increment,
  110. user_id bigint(20) NOT NULL default '0',
  111. url text,
  112. hash char(32),
  113. PRIMARY KEY (uurl_id),
  114. UNIQUE KEY uurl (hash),
  115. KEY url (url(30)),
  116. KEY user_id (user_id)
  117. ) CHARACTER SET latin1");
  118. $result = $this->get_result("CREATE TABLE openid_nonces (\n".
  119. " server_url VARCHAR(255),\n".
  120. " timestamp INTEGER,\n".
  121. " salt CHAR(40),\n".
  122. " UNIQUE (server_url(255), timestamp, salt)\n".
  123. ") CHARACTER SET latin1");
  124. //CREATE TABLE openid_identities ( uurl_id int NOT NULL, user_id int NOT NULL default '0', url text, hash char(32) )
  125. //CREATE TABLE oauth_consumers (consumer_key CHAR(255) PRIMARY KEY, secret CHAR(40), description CHAR(40));
  126. $result = $this->get_result("CREATE TABLE IF NOT EXISTS oauth_consumers (consumer_key CHAR(255) PRIMARY KEY, secret CHAR(40), description CHAR(40)) CHARACTER SET latin1");
  127. //CREATE TABLE oauth_tokens (consumer_key CHAR(40), token CHAR(40), secret CHAR(40), token_type CHAR(7), nonce CHAR(40), user_id INT DEFAULT 0, expires INT DEFAULT 0);
  128. $result = $this->get_result("CREATE TABLE IF NOT EXISTS oauth_tokens (consumer_key CHAR(255), token CHAR(40), secret CHAR(40), token_type CHAR(7), nonce CHAR(40), user_id TINYINT DEFAULT 0, expires INT DEFAULT 0) CHARACTER SET latin1");
  129. //
  130. $result = $this->get_result("INSERT INTO oauth_consumers (consumer_key, secret, description) VALUES ('DUMMYKEY', '', 'Unidentified Consumer')");
  131. //CREATE TABLE openid_nonces ( server_url VARCHAR(2047), timestamp INT, salt CHAR(40) );
  132. //CREATE TABLE openid_associations ( server_url oid, handle VARCHAR(255), secret oid, issued INTEGER, lifetime INTEGER, assoc_type VARCHAR(64) );
  133. $result = $this->get_result("CREATE TABLE openid_associations (\n".
  134. " server_url BLOB,\n".
  135. " handle VARCHAR(255),\n".
  136. " secret BLOB,\n".
  137. " issued INTEGER,\n".
  138. " lifetime INTEGER,\n".
  139. " assoc_type VARCHAR(64),\n".
  140. " PRIMARY KEY (server_url(255), handle)\n".
  141. ") CHARACTER SET latin1");
  142. }
  143. function get_result( $sql, $returnfalse = NULL ) { /* run an SQL query */
  144. trigger_before( 'get_result', $this, $this );
  145. global $request;
  146. if (isset($request->params))
  147. trigger_before( 'get_result', $request, $this );
  148. $result = @mysql_query( $sql, $this->conn );
  149. if (!$result && $returnfalse == NULL) {
  150. trigger_error("error in get_result in mysql.php ".@mysql_error($this->conn)." ".$sql, E_USER_ERROR );
  151. exit;
  152. } elseif (!$result && $returnfalse) {
  153. return false;
  154. } else {
  155. return $result;
  156. }
  157. }
  158. function next_primary_key($table,$pkfield,$sequence_name=NULL) {
  159. trigger_before( 'next_primary_key', $this, $this );
  160. return "";
  161. }
  162. function last_insert_id( &$result, $pk, $table ) { /* returns the id of the most recently modified record */
  163. trigger_before( 'last_insert_id', $this, $this );
  164. $res = @mysql_insert_id($this->conn);
  165. if (!$res) {
  166. trigger_error("unable to determine last_insert_id in mysql.php ".@mysql_error($this->conn), E_USER_ERROR );
  167. } else {
  168. return $res;
  169. }
  170. }
  171. function result_value( &$result, $resultindex, $field ) { /* get a single value from a result set */
  172. trigger_before( 'result_value', $this, $this );
  173. $res = mysql_result( $result, $resultindex, $field );
  174. if (!$res && $res != 0) {
  175. trigger_error("error in result_value in mysql.php".@mysql_error($this->conn), E_USER_ERROR );
  176. } else {
  177. return $res;
  178. }
  179. }
  180. function close() {
  181. trigger_before( 'close', $this, $this );
  182. $args = func_get_args();
  183. mysql_close( $this->conn );
  184. if ( isset( $args[0] ) ) {
  185. if ( strlen($args[0]) > 0 ) {
  186. header( "Location:" . $args[0] );
  187. exit;
  188. }
  189. }
  190. }
  191. function &get_table($table) {
  192. trigger_before( 'get_table', $this, $this );
  193. if ( isset( $this->models[$table] ) )
  194. if ($this->models[$table]->exists)
  195. return $this->models[$table];
  196. $custom_class = classify($table);
  197. if (!isset($this->models[$table]) && class_exists($custom_class)) {
  198. $this->models[$table] = new $custom_class();
  199. } elseif (!isset($this->models[$table])) {
  200. $this->models[$table] = new Model($table, $this);
  201. }
  202. if (!($this->models[$table]->exists))
  203. $this->models[$table]->register($table);
  204. return $this->models[$table];
  205. }
  206. function &model($model) {
  207. trigger_before( 'model', $this, $this );
  208. return $this->get_table(tableize($model));
  209. }
  210. function fetch_array(&$result,$row=NULL) {
  211. trigger_before( 'fetch_array', $this, $this );
  212. if (is_numeric($row)) {
  213. $this->seek_row( $result, $row );
  214. }
  215. return mysql_fetch_array( $result, MYSQL_ASSOC );
  216. }
  217. function fetch_row(&$result,$row=NULL) {
  218. trigger_before( 'fetch_row', $this, $this );
  219. if (is_numeric($row)) {
  220. $this->seek_row( $result, $row );
  221. }
  222. return mysql_fetch_row( $result );
  223. }
  224. function seek_row(&$result,$row) {
  225. trigger_before( 'seek_row', $this, $this );
  226. return mysql_data_seek( $result, $row );
  227. }
  228. function query_limit($limit,$offset) {
  229. trigger_before( 'query_limit', $this, $this );
  230. return " LIMIT " . $offset . "," . $limit;
  231. }
  232. function blob_value( &$rec, $field, &$value ) {
  233. trigger_before( 'blob_value', $this, $this );
  234. $ret = array();
  235. $ret['t'] = $rec->table;
  236. $ret['f'] = $field;
  237. $ret['k'] = $rec->primary_key;
  238. $ret['i'] = $rec->attributes[$rec->primary_key];
  239. return $ret;
  240. }
  241. function sql_insert_for( &$rec ) {
  242. trigger_before( 'sql_insert_for', $this, $this );
  243. $sql = "INSERT INTO " . $this->prefix.$rec->table . " (";
  244. $comma = '';
  245. $fields = '';
  246. $values = '';
  247. foreach (array_unique($rec->modified_fields) AS $modified_field) {
  248. $datatype = $this->get_mapped_datatype($this->models[$rec->table]->field_array[$modified_field]);
  249. $this->pre_insert( $rec, $modified_field, $datatype );
  250. if ( !( $datatype == 'blob' && ( !(strlen( $rec->attributes[$modified_field] ) > 0 ) ) ) ) {
  251. $fields .= $comma . $modified_field;
  252. $values .= $comma . $this->quoted_insert_value( $rec, $modified_field );;
  253. $comma = ',';
  254. }
  255. }
  256. $sql .= $fields . ") VALUES (" . $values . ")";
  257. return $sql;
  258. }
  259. function sql_update_for( &$rec ) {
  260. trigger_before( 'sql_update_for', $this, $this );
  261. $sql = "UPDATE ";
  262. $sql .= $this->prefix.$rec->table . ' SET ';
  263. $comma = '';
  264. foreach (array_unique($rec->modified_fields) AS $modified_field) {
  265. $datatype = $this->get_mapped_datatype($this->models[$rec->table]->field_array[$modified_field]);
  266. $this->pre_update( $rec, $modified_field, $datatype );
  267. if ( !( $datatype == 'blob' && ( !(strlen( $rec->attributes[$modified_field] ) > 0 ) ) ) ) {
  268. $sql .= $comma . $this->quoted_update_value( $rec, $modified_field );
  269. $comma = ',';
  270. }
  271. }
  272. $sql .= " WHERE " . $rec->primary_key . "='" . $rec->attributes[$rec->primary_key] . "'";
  273. return $sql;
  274. }
  275. function sql_select_for( &$rec, $id ) {
  276. trigger_before( 'sql_select_for', $this, $this );
  277. return "SELECT ".$rec->selecttext." FROM ".$this->prefix.$rec->table." WHERE ".$rec->primary_key." = '".$id."'";
  278. }
  279. function sql_delete_for( &$rec ) {
  280. trigger_before( 'sql_delete_for', $this, $this );
  281. $pkfield = $rec->primary_key;
  282. $sql = 'DELETE FROM ' . $this->prefix.$rec->table . ' WHERE ' . $rec->primary_key . ' = ' . $rec->$pkfield;
  283. return $sql;
  284. }
  285. function select_distinct( $field, $table, $orderby ) {
  286. trigger_before( 'select_distinct', $this, $this );
  287. return "SELECT DISTINCT $field, " . $this->models[$table]->primary_key . " FROM ".$this->prefix."$table ORDER BY $orderby DESC";
  288. }
  289. function quoted_update_value( &$rec, $modified_field ) {
  290. trigger_before( 'quoted_update_value', $this, $this );
  291. return $modified_field . "='" . $this->escape_string($rec->attributes[$modified_field]) . "'";
  292. }
  293. function quoted_insert_value( &$rec, $modified_field ) {
  294. trigger_before( 'quoted_insert_value', $this, $this );
  295. return "'" . $this->escape_string($rec->attributes[$modified_field]) . "'";
  296. }
  297. function pre_insert( &$rec, $modified_field, $datatype ) {
  298. trigger_before( 'pre_insert', $rec, $this );
  299. global $request;
  300. $req =& $request;
  301. if (isset($this->models[$rec->table]->field_attrs[$modified_field]['required'])) {
  302. if (!(strlen( $rec->attributes[$modified_field] ) > 0))
  303. trigger_error( "$modified_field is a required field", E_USER_ERROR );
  304. }
  305. if (isset($this->models[$rec->table]->field_attrs[$modified_field]['unique'])) {
  306. $result = $this->get_result("select ".$modified_field." from ".$this->prefix.$rec->table." where ".$modified_field." = '".$rec->attributes[$modified_field]."'");
  307. if ($result && $this->num_rows($result) > 0)
  308. trigger_error( "Sorry but that $modified_field has already been taken.", E_USER_ERROR );
  309. }
  310. if ($datatype == 'time' && !(strlen($rec->attributes[$modified_field]) > 0))
  311. $rec->attributes[$modified_field] = date("Y-m-d H:i:s",strtotime("now"));
  312. if ($datatype == 'blob' && !(empty($req->params[strtolower(classify($rec->table))][$modified_field]))) {
  313. if (environment('max_upload_mb')) {
  314. $max = 1048576*environment('max_upload_mb');
  315. $size = filesize($rec->attributes[$modified_field]);
  316. if ($size >$max)
  317. trigger_error('Sorry but that file is too big, the limit is '.environment('max_upload_mb').' megabytes', E_USER_ERROR);
  318. }
  319. $coll = environment('collection_cache');
  320. if (isset($coll[$request->resource]) && $coll[$request->resource]['location'] == 'aws') {
  321. $this->file_upload = array($modified_field,$rec->attributes[$modified_field]);
  322. $rec->set_value($modified_field,'');
  323. } elseif (isset($coll[$request->resource]) && $coll[$request->resource]['location'] == 'uploads') {
  324. $this->file_upload = $rec->attributes[$modified_field];
  325. $rec->set_value($modified_field,'');
  326. } else {
  327. $rec->attributes[$modified_field] =& $this->large_object_create( $this->prefix.$rec->table, $rec->attributes[$modified_field] );
  328. }
  329. }
  330. if ($datatype == 'bool') {
  331. if ( in_array( $rec->attributes[$modified_field], $this->true_values, true ) ) {
  332. $rec->attributes[$modified_field] = "1";
  333. } else {
  334. $rec->attributes[$modified_field] = "false";
  335. }
  336. }
  337. }
  338. function pre_update( &$rec, $modified_field, $datatype ) {
  339. trigger_before( 'pre_update', $rec, $this );
  340. global $request;
  341. $req =& $request;
  342. if (isset($this->models[$rec->table]->field_attrs[$modified_field]['required'])) {
  343. if (!(strlen( $rec->attributes[$modified_field] ) > 0))
  344. trigger_error( "$modified_field is a required field", E_USER_ERROR );
  345. }
  346. if (isset($this->models[$rec->table]->field_attrs[$modified_field]['unique'])) {
  347. $result = $this->get_result("select ".$modified_field." from ".$this->prefix.$rec->table." where ".$modified_field." = '".$rec->attributes[$modified_field]."' and ".$rec->primary_key." != '".$rec->attributes[$rec->primary_key]."'");
  348. if ($this->num_rows($result) > 0)
  349. trigger_error( "Sorry but that $modified_field has already been taken.", E_USER_ERROR );
  350. }
  351. if ($datatype == 'bool') {
  352. if ( in_array( $rec->attributes[$modified_field], $this->true_values, true ) ) {
  353. $rec->attributes[$modified_field] = "1";
  354. } else {
  355. $rec->attributes[$modified_field] = "false";
  356. }
  357. }
  358. if ($datatype == 'blob' && !(empty($req->params[strtolower(classify($rec->table))][$modified_field]))) {
  359. if ( strlen( $rec->attributes[$modified_field] ) > 0 ) {
  360. if (environment('max_upload_mb')) {
  361. $max = 1048576*environment('max_upload_mb');
  362. $size = filesize($rec->attributes[$modified_field]);
  363. if ($size >$max)
  364. trigger_error('Sorry but that file is too big, the limit is '.environment('max_upload_mb').' megabytes', E_USER_ERROR);
  365. }
  366. $coll = environment('collection_cache');
  367. if (isset($coll[$request->resource]) && $coll[$request->resource]['location'] == 'aws') {
  368. $this->file_upload = array($modified_field,$rec->attributes[$modified_field]);
  369. $this->aws_delfile($rec,$rec->id);
  370. $this->aws_putfile($rec,$rec->id);
  371. $rec->set_value($modified_field,'');
  372. } elseif (isset($coll[$request->resource]) && $coll[$request->resource]['location'] == 'uploads') {
  373. update_uploadsfile($this->prefix.$rec->table,$rec->id,$rec->attributes[$modified_field]);
  374. $rec->set_value($modified_field,'');
  375. } else {
  376. unlink_cachefile($this->prefix.$rec->table,$rec->id,$coll);
  377. $data =& $this->large_object_create($this->prefix.$rec->table,$rec->attributes[$modified_field]);
  378. $rec->attributes[$modified_field] =& $data;
  379. }
  380. }
  381. }
  382. }
  383. function post_insert( &$rec, &$result ) {
  384. trigger_before( 'post_insert', $this, $this );
  385. if (!$result) { trigger_error("Sorry, the record could not be saved due to a database error.", E_USER_ERROR ); }
  386. $pkvalue = $this->last_insert_id($result,NULL,NULL);
  387. if (is_array($this->file_upload))
  388. $this->aws_putfile($rec,$pkvalue);
  389. elseif (!empty($this->file_upload))
  390. update_uploadsfile($this->prefix.$rec->table,$pkvalue,$this->file_upload);
  391. $pkfield = $rec->primary_key;
  392. $rec->attributes[$pkfield] = $pkvalue;
  393. $rec->$pkfield =& $rec->attributes[$pkfield];
  394. }
  395. function affected_rows(&$result) {
  396. trigger_before( 'affected_rows', $this, $this );
  397. return @mysql_affected_rows($result);
  398. }
  399. function fetch_field(&$result,$i) {
  400. trigger_before( 'fetch_field', $this, $this );
  401. return @mysql_fetch_field($result,$i);
  402. }
  403. function fetch_object(&$result) {
  404. trigger_before( 'fetch_object', $this, $this );
  405. return @mysql_fetch_object($result);
  406. }
  407. function num_rows(&$result) {
  408. trigger_before( 'num_rows', $this, $this );
  409. return @mysql_num_rows($result);
  410. }
  411. function num_fields(&$result) {
  412. trigger_before( 'num_fields', $this, $this );
  413. return @mysql_num_fields($result);
  414. }
  415. function field_name(&$result, $index) {
  416. trigger_before( 'field_name', $this, $this );
  417. return @mysql_field_name($result, $index);
  418. }
  419. function large_object_create($table,$file) {
  420. trigger_before( 'large_object_create', $this, $this );
  421. $return = false;
  422. if (is_array($file))
  423. return $return;
  424. if (!(file_exists($file))) { trigger_error("temporary file $file could not be found", E_USER_ERROR ); }
  425. $handle = fopen($file,"r");
  426. if (!$handle) { trigger_error("Error creating large object in fopen", E_USER_ERROR ); }
  427. $buffer = fread($handle,filesize($file));
  428. if (!$buffer) { trigger_error("Error creating large object in fread", E_USER_ERROR ); }
  429. $result = fclose($handle);
  430. if (!$result) { trigger_error("Error creating large object in fclose", E_USER_ERROR ); }
  431. else {
  432. $return =& $buffer;
  433. }
  434. return $return;
  435. }
  436. function large_object_fetch($table,$blobcol,$pkfield,$pkvalue, $return=false) {
  437. trigger_before( 'large_object_fetch', $this, $this );
  438. // t f k i
  439. $sql = "SELECT $blobcol FROM $this->prefix"."$table WHERE $pkfield = '$pkvalue'";
  440. $result = $this->get_result($sql);
  441. if ($result && $return)
  442. return $this->result_value($result,0,$blobcol);
  443. elseif ($result)
  444. print $this->result_value($result,0,$blobcol);
  445. return false;
  446. }
  447. function large_object_delete($oid) {
  448. trigger_before( 'large_object_delete', $this, $this );
  449. return true;
  450. }
  451. function add_table( $table, $field_array ) {
  452. trigger_before( 'add_table', $this, $this );
  453. $exists = $this->get_tables();
  454. if (in_array($this->prefix.$table,$exists))
  455. return true;
  456. if (!(count($field_array)>0)) trigger_error( "Error creating table, no fields are defined. Use \$model->auto_field and \$model->text_field etc.", E_USER_ERROR );
  457. $sql = "CREATE TABLE ".$this->prefix."$table (";
  458. $comma = "";
  459. foreach ( $field_array as $field => $data_type ) {
  460. $sql .= "$comma $field $data_type";
  461. $comma = ",";
  462. }
  463. $sql .= ") CHARACTER SET utf8";
  464. $result = $this->get_result($sql);
  465. if ($result)
  466. $this->tables[] = $this->prefix.$table;
  467. }
  468. function add_field( $table, $field, $data_type ) {
  469. $table = $this->prefix.$table;
  470. trigger_before( 'add_field', $this, $this );
  471. $sql = "ALTER TABLE $table ADD COLUMN $field $data_type";
  472. $result = $this->get_result($sql);
  473. }
  474. function has_table($t) {
  475. trigger_before( 'has_table', $this, $this );
  476. $t = $this->prefix.$t;
  477. if (!(isset($this->tables)))
  478. $this->tables = $this->get_tables();
  479. return in_array( $t, $this->tables, true );
  480. }
  481. function get_tables() {
  482. trigger_before( 'get_tables', $this, $this );
  483. $tables = array();
  484. $sql = "SHOW tables";
  485. $result = $this->get_result($sql);
  486. while ($arr = $this->fetch_array($result)) {
  487. foreach($arr as $key=>$value) {
  488. foreach(array('db_sessions') as $skip)
  489. if (!(strstr($value,$skip)))
  490. $tables[] = $value;
  491. }
  492. }
  493. return $tables;
  494. }
  495. function get_fields($table) {
  496. trigger_before( 'get_fields', $this, $this );
  497. $datatypes = array();
  498. $sql = "SHOW columns FROM ".$this->prefix.$table;
  499. $result = $this->get_result($sql, true);
  500. if (!$result) return $datatypes;
  501. while ($arr = $this->fetch_array($result)) {
  502. foreach($arr as $key=>$value) {
  503. if ($key == "Field") {
  504. $field = $value;
  505. } elseif ($key == "Type") {
  506. $type = $value;
  507. } elseif ($key == "Key") {
  508. if ($value == "PRI") {
  509. $datatypes[$table."_primary_key"] = $field; // yuck
  510. }
  511. }
  512. }
  513. $datatypes[$field] = $type;
  514. }
  515. return $datatypes;
  516. }
  517. function auto_field( $field, &$model ) {
  518. $model->set_field( $field, "int(11) not null auto_increment primary key" );
  519. $model->set_primary_key( $field );
  520. }
  521. function enum_field( $field, $values, &$model ) {
  522. $model->set_field( $field, "enum", $values );
  523. }
  524. function float_field( $field, &$model ) {
  525. $model->set_field( $field, "double" );
  526. }
  527. function bool_field( $field, &$model ) {
  528. $model->set_field( $field, "bool" );
  529. }
  530. function char_field( $field, &$model, $options ) {
  531. if (!(isset($options['len'])))
  532. $options = array('len'=>255);
  533. $model->set_field( $field, "varchar(".$options['len'].")" );
  534. }
  535. function date_field( $field, &$model ) {
  536. $model->set_field( $field, "date" );
  537. }
  538. function file_field( $field, &$model ) {
  539. $model->set_field( $field, "longblob" );
  540. }
  541. function int_field( $field, &$model ) {
  542. $model->set_field( $field, "int(11)" );
  543. }
  544. function text_field( $field, &$model ) {
  545. $model->set_field( $field, "text" );
  546. }
  547. function time_field( $field, &$model ) {
  548. $model->set_field( $field, "datetime" );
  549. }
  550. function get_query( $id=NULL, $find_by=NULL, &$model ) {
  551. if (isset($model->query)) {
  552. $q = $model->query;
  553. unset($model->query);
  554. return $q;
  555. }
  556. if (!($id==NULL))
  557. $model->set_param('id',$id);
  558. if ($find_by == NULL && !isset($model->find_by))
  559. $model->set_param('find_by',$model->primary_key);
  560. elseif (!($find_by == NULL))
  561. $model->set_param('find_by',$find_by);
  562. trigger_before( 'get_query', $model, $this );
  563. $pkfield = $model->primary_key;
  564. $relfields = array();
  565. $relfields = $model->relations;
  566. $table = $this->prefix.$model->table;
  567. $fieldstring = '';
  568. $sql = "SELECT " . "\n";
  569. if (!array_key_exists($pkfield,$model->field_array))
  570. $sql .= "$table.$pkfield as \"$table.$pkfield\", " . "\n";
  571. foreach ($model->field_array as $fieldname=>$datatypename) {
  572. // loop to add each field to the sql query
  573. if (strpos($fieldname,".") === false)
  574. $fieldname = $table . "." . $fieldname;
  575. else
  576. $fieldname = $this->prefix.$fieldname;
  577. $fieldstring .= "$fieldname as \"$fieldname\", " . "\n";
  578. }
  579. $leftsql = "";
  580. $first = true;
  581. if (count($relfields) > 0) {
  582. foreach ($relfields as $key=>$val) {
  583. $spl = split("\.",$val["fkey"]);
  584. if (!($this->models[$spl[0]]->exists))
  585. $$spl[0] =& $this->get_table($spl[0]);
  586. $leftsql .= "(";
  587. }
  588. foreach ($relfields as $key=>$val) {
  589. $spl = split("\.",$val["fkey"]);
  590. if (($val["type"] == 'child-many')) {
  591. $join =& $this->get_table($model->join_table_for($model->table, $val['tab']));
  592. $spl[0] = $join->table;
  593. $val["fkey"] = $join->table.'.'.strtolower(classify($model->table))."_".$model->foreign_key_for( $model->table);
  594. }else{
  595. foreach ($this->models[$spl[0]]->field_array as $fieldname=>$datatypename) {
  596. $fieldstring .= $this->prefix.$spl[0].".".$fieldname." as \"".$this->prefix.$spl[0].".".$fieldname."\", " . "\n";
  597. }
  598. }
  599. if ($first)
  600. $leftsql .= $table;
  601. $leftsql .= " left join " . $this->prefix.$spl[0] . " on ".$table.".".$val["col"]." = " .$this->prefix.$val["fkey"];
  602. $leftsql .= ")";
  603. $first = false;
  604. }
  605. }
  606. $fieldstring = substr($fieldstring,0,-3) . " " . "\n";
  607. $sql .= $fieldstring;
  608. $sql .= "FROM ";
  609. $sql .= $leftsql;
  610. if (!(strlen($leftsql) > 1))
  611. $sql .= $table;
  612. if (is_array($model->find_by)) {
  613. $findfirst = true;
  614. $op = "AND";
  615. $eq = '=';
  616. foreach( $model->find_by as $col=>$val ) {
  617. if (is_array($val))
  618. list($col,$val) = each($val);
  619. if ($col == 'op') {
  620. $op = $val;
  621. } elseif ($col =='eq') {
  622. $eq = $val;
  623. } else {
  624. if (strpos($col,".") === false)
  625. $field = "$table.$col";
  626. else
  627. $field = $this->prefix.$col;
  628. if ($eq == 'IS')
  629. $eqval = $val;
  630. else
  631. $eqval = "'$val'";
  632. if ($findfirst) {
  633. $sql .= " WHERE $field $eq $eqval ";
  634. } else {
  635. $sql .= " $op $field $eq $eqval ";
  636. }
  637. $findfirst = false;
  638. }
  639. }
  640. } elseif ($model->id != NULL) {
  641. if (strpos($model->find_by,".") === false)
  642. $field = $table.".".$model->find_by;
  643. else
  644. $field = $model->find_by;
  645. if (strpos($field,".") === false)
  646. $field = "$table.$field";
  647. $sql .= " WHERE $field = '".$model->id."' ";
  648. }
  649. if (!(isset($model->orderby))) {
  650. $model->orderby = $table . "." . $pkfield;
  651. }
  652. if (!(isset($model->order))) {
  653. $model->order = "DESC";
  654. }
  655. if (!(isset($model->offset))) {
  656. $model->offset = 0;
  657. }
  658. if (!(isset($model->limit))) {
  659. $model->limit = 20;
  660. }
  661. if (isset($model->groupby))
  662. $sql .= " GROUP BY " . $model->groupby . " ";
  663. if (strpos($model->orderby,".") === false)
  664. $model->orderby = "$table.".$model->orderby;
  665. if ($this->prefix && !(substr($model->orderby,0,3) == $this->prefix)){
  666. $spl = split("\.",$model->orderby);
  667. if (count($spl)==2){
  668. $model->orderby = "$table.".$spl[1];
  669. }
  670. }
  671. $sql .= " ORDER BY " . $model->orderby . " ";
  672. $sql .= $model->order . $this->query_limit($model->limit,$model->offset);
  673. trigger_after( 'get_query', $model, $this );
  674. //if ($model->table == 'people') { echo $sql; exit; }
  675. return $sql;
  676. }
  677. }
  678. ?>