PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/core/database/class.database.query.runners.php

http://buddypress-media.googlecode.com/
PHP | 1157 lines | 501 code | 270 blank | 386 comment | 118 complexity | 8fb367829babe498529ae336d64a3465 MD5 | raw file
Possible License(s): AGPL-1.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * BP-MEDIA DATABASE QUERY RUNNER CLASS
  4. * Runs pre-built queries against the SQL server and returns formatted results
  5. *
  6. * @version 0.1.9
  7. * @since 0.1.9
  8. * @package BP-Media
  9. * @subpackage Database
  10. * @license GPL v2.0
  11. * @link http://code.google.com/p/buddypress-media/wiki/DOCS_BPM_db_top
  12. *
  13. * ========================================================================================================
  14. */
  15. class BPM_queryRunner {
  16. var $parent; // Reference to parent class
  17. // ============================================================================================================ //
  18. function BPM_queryRunner(&$parent_class) {
  19. $this->__construct($parent_class);
  20. }
  21. function __construct(&$parent_class){
  22. // We link the $parent var inside this class to the instance of the parent class passed in
  23. // the constructor. This means we can access any variable or function inside the parent class
  24. // as "$this->parent->varName"
  25. $this->parent =& $parent_class;
  26. }
  27. /**
  28. * Runs a query on the database. Returns results in a specific format.
  29. *
  30. * @version 0.1.9
  31. * @since 0.1.9
  32. * @link http://code.google.com/p/buddypress-media/wiki/DOCS_BPM_db_select_formatter
  33. *
  34. * @param string $sql | SQL query string
  35. *
  36. * @param array $ctrl | Control parameters for the query
  37. * => VAL @param string $format | Return format for query: "col", "row", "var", "array_key_object", "array_key_array"
  38. * "array_key_single", "array_object", "array_array", "raw", or (null)
  39. * @see result formatter headers inside this method for detailed docs
  40. *
  41. * => VAL @see BPM_db::runSelectQuery() and BPM_db::runSelectQueryJoin() for docs on remaining $ctrl options
  42. *
  43. * @return bool | Exception on failure. Query results array on success.
  44. */
  45. public function runQuery($query, $ctrl=null){
  46. if($this->parent->print_query_args == true){
  47. ob_start();
  48. print_r($query);
  49. print_r($ctrl);
  50. $out = ob_get_clean();
  51. BPM_debug::addToFile($out);
  52. }
  53. // Trap invalid return formats
  54. // ==============================
  55. $valid_formats = array(
  56. "1" => "col",
  57. "2" => "row",
  58. "3" => "var",
  59. "4" => "array_key_object",
  60. "5" => "array_key_array",
  61. "6" => "array_key_single",
  62. "7" => "array_object",
  63. "8" => "array_array",
  64. "10" => "raw",
  65. "11" => null,
  66. );
  67. if( array_search( $ctrl["format"], $valid_formats) === null) {
  68. throw new BPM_exception( array(
  69. 'numeric'=>1,
  70. 'data'=>array('faulting_format'=>$ctrl["format"],"query"=>$query, "ctrl"=>$ctrl),
  71. 'file'=>__FILE__, 'line'=>__LINE__, 'method'=>__METHOD__,
  72. 'child'=>null
  73. ));
  74. }
  75. // Handle single parameter as string/int, or multiple
  76. // parameters passed as an array
  77. // ==================================================
  78. if( is_array($query) ){
  79. $sql = call_user_func_array( array($this->parent->db, "prepare"), $query["query"]);
  80. }
  81. else {
  82. $sql = $query;
  83. $ctrl = array("format"=>null);
  84. }
  85. if($this->parent->print_query_sql == true){
  86. BPM_debug::addToFile($sql);
  87. }
  88. // EXAMPLE TABLE "test_table"
  89. // =================================
  90. // col_1 | col_2 | col_3 | col_4 |
  91. // =================================
  92. // 1 | red | dog | big |
  93. // 2 | green| cat | med |
  94. // 3 | blue | bird | small |
  95. // 4 | black| fish | tiny |
  96. $cast = new BPM_cast();
  97. switch($ctrl["format"]){
  98. // VAR
  99. // =============================================================================
  100. // Used when fetching query results that return a single variable.
  101. //
  102. // EXAMPLE: "SELECT COUNT(*) FROM test_table WHERE col_2 = red"
  103. // RESULT: string "1" (all data is returned in string format)
  104. case "var" : {
  105. $result = $this->parent->db->get_var($sql);
  106. if($this->parent->print_result_raw == true){
  107. ob_start();
  108. echo "\nRAW, format = var\n";
  109. print_r($result);
  110. $out = ob_get_clean();
  111. BPM_debug::addToFile($out);
  112. }
  113. if($this->parent->disable_typecast_read == false){
  114. $cast->queryResult($format="var", $result, $query["types"]);
  115. if($this->parent->print_result_cast == true){
  116. ob_start();
  117. echo "\nCAST, format = var\n";
  118. print_r($result);
  119. $out = ob_get_clean();
  120. BPM_debug::addToFile($out);
  121. }
  122. }
  123. } break;
  124. // COL
  125. // =============================================================================
  126. // Used when fetching query results which only contain values from a single column.
  127. //
  128. // EXAMPLE: "SELECT col2 FROM test_table"
  129. // RESULT: array("red", "green", "blue", "black")
  130. case "col" : {
  131. $result = $this->parent->db->get_col($sql);
  132. if($this->parent->print_result_raw == true){
  133. ob_start();
  134. echo "\nRAW, format = col\n";
  135. print_r($result);
  136. $out = ob_get_clean();
  137. BPM_debug::addToFile($out);
  138. }
  139. if($this->parent->disable_typecast_read == false){
  140. $cast->queryResult($format="col", $result, $query["types"]);
  141. if($this->parent->print_result_cast == true){
  142. ob_start();
  143. echo "\nCAST, format = col\n";
  144. print_r($result);
  145. $out = ob_get_clean();
  146. BPM_debug::addToFile($out);
  147. }
  148. }
  149. } break;
  150. // ROW_OBJECT
  151. // =============================================================================
  152. // Returns a single database row as an object, with variable names mapped to
  153. // column names. If the query returns multiple rows, only the first row is returned.
  154. //
  155. // EXAMPLE: "SELECT * FROM test_table WHERE col_1 = 2"
  156. // RESULT: object stdClass(
  157. // col_1->2
  158. // col_2->"green"
  159. // col_3->"cat"
  160. // col_4->"med"
  161. // )
  162. case "row_object" : {
  163. $result = $this->parent->db->get_row($sql);
  164. if($this->parent->print_result_raw == true){
  165. ob_start();
  166. echo "\nRAW, format = row\n";
  167. print_r($result);
  168. $out = ob_get_clean();
  169. BPM_debug::addToFile($out);
  170. }
  171. if($this->parent->disable_typecast_read == false){
  172. $cast->queryResult($format="row_object", $result, $query["types"]);
  173. if($this->parent->print_result_cast == true){
  174. ob_start();
  175. echo "\nCAST, format = row_object\n";
  176. print_r($result);
  177. $out = ob_get_clean();
  178. BPM_debug::addToFile($out);
  179. }
  180. }
  181. } break;
  182. // ROW_ARRAY
  183. // =============================================================================
  184. // Returns a single database row as an array, with key names mapped to column
  185. // names. If the query returns multiple rows, only the first row is returned.
  186. //
  187. // EXAMPLE: "SELECT * FROM test_table WHERE col_1 = 2"
  188. // RESULT: array(
  189. // "col_1"=>2
  190. // "col_2"=>"green"
  191. // "col_3"=>"cat"
  192. // "col_4"=>"med"
  193. // )
  194. case "row_array" : {
  195. $data = $this->parent->db->get_row($sql);
  196. if($this->parent->print_result_raw == true){
  197. ob_start();
  198. echo "\nRAW, format = row_array\n";
  199. print_r($data);
  200. $out = ob_get_clean();
  201. BPM_debug::addToFile($out);
  202. }
  203. if($this->parent->disable_typecast_read == false){
  204. $cast->queryResult($format="row_object", $data, $query["types"]);
  205. if($this->parent->print_result_cast == true){
  206. ob_start();
  207. echo "\nCAST, format = row_array\n";
  208. print_r($data);
  209. $out = ob_get_clean();
  210. BPM_debug::addToFile($out);
  211. }
  212. }
  213. if($data){
  214. $result = array();
  215. // Convert row object into array
  216. foreach($data as $key => $value){
  217. $result[$key] = $value;
  218. }
  219. if($this->parent->print_result_formatted == true){
  220. ob_start();
  221. echo "\nFORMATTED, format = row_array\n";
  222. print_r($result);
  223. $out = ob_get_clean();
  224. BPM_debug::addToFile($out);
  225. }
  226. unset($data); // Reduce memory usage
  227. }
  228. } break;
  229. // ARRAY_KEY_OBJECT
  230. // =============================================================================
  231. //
  232. // When used with a single column name passed as a string:
  233. //
  234. // Returns results as an array of objects, where the primary array key names are
  235. // set based on the contents of a database column.
  236. //
  237. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"]="col_3"
  238. // RESULT: array(
  239. // "dog" =>stdClass( "col_1"->1, "col_2"->"red", "col_3"->"dog", "col_4"->"big"),
  240. // "cat" =>stdClass( "col_1"->2, "col_2"->"green", "col_3"->"cat", "col_4"->"med"),
  241. // "bird"=>stdClass( "col_1"->3, "col_2"->"blue", "col_3"->"bird", "col_4"->"small"),
  242. // "fish"=>stdClass( "col_1"->4, "col_2"->"black", "col_3"->"fish", "col_4"->"tiny"),
  243. // )
  244. // When used with multiple column names passed as an array of strings:
  245. //
  246. // Returns results as an array of arrays^N, where the array key names and heirarchy
  247. // are set based on the contents of the $key_col array. This output format REQUIRES
  248. // that each taxonomy group (in the example below "col_3" + "col_4") is UNIQUE
  249. //
  250. // EXAMPLE TABLE "test_table_2"
  251. // ======================================
  252. // col_1 | col_2 | col_3 | col_4 | col_5
  253. // ======================================
  254. // 1 | red | dog | big | heavy
  255. // 2 | green| dog | med | light
  256. // 3 | blue | bird | small | light
  257. // 4 | black| fish | tiny | average
  258. // 5 | black| fish | large | light
  259. //
  260. // UNIQUE KEY col_3_col4(col_3, col_4)
  261. //
  262. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"] = array("col_3, "col_4")
  263. // RESULT: array(
  264. // "dog" =>array(
  265. // "big"=>stdClass("col_1"->1, "col_2"->"red", "col_5"->"heavy"),
  266. // "med"=>stdClass("col_1"->2, "col_2"->"green", "col_5"->"light")
  267. // ),
  268. // "bird"=>array(
  269. // "small"=>stdClass("col_1"->3, "col_2"->"blue", "col_5"->"light")
  270. // ),
  271. // "fish"=>array(
  272. // "tiny"=>stdClass("col_1"->4, "col_2"->"black", "col_5"->"average"),
  273. // "large"=>stdClass("col_1"->5, "col_2"->"black", "col_5"->"light")
  274. // )
  275. // )
  276. case "array_key_object" : {
  277. $data = $this->parent->db->get_results($sql);
  278. if($this->parent->print_result_raw == true){
  279. ob_start();
  280. echo "\nRAW, format = array_key_object\n";
  281. print_r($data);
  282. $out = ob_get_clean();
  283. BPM_debug::addToFile($out);
  284. }
  285. if($this->parent->disable_typecast_read == false){
  286. $cast->queryResult($format="array_object", $data, $query["types"]);
  287. if($this->parent->print_result_cast == true){
  288. ob_start();
  289. echo "\nCAST, format = array_key_object\n";
  290. print_r($data);
  291. $out = ob_get_clean();
  292. BPM_debug::addToFile($out);
  293. }
  294. }
  295. if($data){
  296. $result = array();
  297. // If a single column name is passed as a string, use the more efficient
  298. // direct assignment algorithm to build a 1 level tree
  299. if( !is_array($ctrl["key_col"]) ){
  300. foreach($data as $row){
  301. $key = $row->{$ctrl["key_col"]};
  302. $result[$key] = $row;
  303. }
  304. }
  305. // If an array of column names are passed, use the less efficient eval()
  306. // algorithm to build a n-level deep tree
  307. else {
  308. foreach($data as $row){
  309. // Since there is no functionality in PHP for creating a new array key
  310. // based on a name stored in a variable ( $$ variable variable syntax does
  311. // not work for multidimensional arrays, we have to build a string of PHP
  312. // code and use eval() to run it
  313. $eval_str = "\$result";
  314. foreach($ctrl["key_col"] as $keyname){
  315. $eval_str .= '["' . $row->{$keyname} . '"]';
  316. }
  317. $eval_str .= " = \$row_copy;";
  318. $row_copy = new stdClass();
  319. // Copy the row object into a new stdClass, skipping keys that are used as the
  320. // branch variables
  321. foreach($row as $key => $value){
  322. if( array_search($key, $ctrl["key_col"]) === false ){
  323. $row_copy->{$key} = $value;
  324. }
  325. }
  326. // Run the PHP string we have built
  327. eval($eval_str);
  328. }
  329. }
  330. if($this->parent->print_result_formatted == true){
  331. ob_start();
  332. echo "\nFORMATTED, format = array_key_object\n";
  333. print_r($result);
  334. $out = ob_get_clean();
  335. BPM_debug::addToFile($out);
  336. }
  337. unset($data); // Reduce memory usage
  338. }
  339. } break;
  340. // ARRAY_KEY_ARRAY
  341. // =============================================================================
  342. // When used with a single column name passed as a string:
  343. //
  344. // Returns results as an array of arrays, where the primary array key names are
  345. // set based on the contents of a database column.
  346. //
  347. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"]="col_3"
  348. // RESULT: array(
  349. // "dog" =>array( "col_1"=>1, "col_2"=>"red", "col_3"=>"dog", "col_4"=>"big"),
  350. // "cat" =>array( "col_1"=>2, "col_2"=>"green", "col_3"=>"cat", "col_4"=>"med"),
  351. // "bird"=>array( "col_1"=>3, "col_2"=>"blue", "col_3"=>"bird", "col_4"=>"small"),
  352. // "fish"=>array( "col_1"=>4, "col_2"=>"black", "col_3"=>"fish", "col_4"=>"tiny"),
  353. // )
  354. //
  355. // When used with multiple column names passed as an array of strings:
  356. //
  357. // Returns results as an array of arrays^N, where the array key names and heirarchy
  358. // are set based on the contents of the $key_col array. This output format REQUIRES
  359. // that each taxonomy group (in the example below "col_3" + "col_4") is UNIQUE
  360. //
  361. // EXAMPLE TABLE "test_table_2"
  362. // ======================================
  363. // col_1 | col_2 | col_3 | col_4 | col_5
  364. // ======================================
  365. // 1 | red | dog | big | heavy
  366. // 2 | green| dog | med | light
  367. // 3 | blue | bird | small | light
  368. // 4 | black| fish | tiny | average
  369. // 5 | black| fish | large | light
  370. //
  371. // UNIQUE KEY col_3_col4(col_3, col_4)
  372. //
  373. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"] = array("col_3, "col_4")
  374. // RESULT: array(
  375. // "dog" =>array(
  376. // "big"=>array("col_1"=>1, "col_2"=>"red", "col_5"=>"heavy"),
  377. // "med"=>array("col_1"=>2, "col_2"=>"green", "col_5"=>"light")
  378. // ),
  379. // "bird"=>array(
  380. // "small"=>array("col_1"=>3, "col_2"=>"blue", "col_5"=>"light")
  381. // ),
  382. // "fish"=>array(
  383. // "tiny"=>array("col_1"=>4, "col_2"=>"black", "col_5"=>"average"),
  384. // "large"=>array("col_1"=>5, "col_2"=>"black", "col_5"=>"light")
  385. // )
  386. // )
  387. case "array_key_array" : {
  388. $data = $this->parent->db->get_results($sql);
  389. if($this->parent->print_result_raw == true){
  390. ob_start();
  391. echo "RAW, format = array_key_array\n";
  392. print_r($data);
  393. $out = ob_get_clean();
  394. BPM_debug::addToFile($out);
  395. }
  396. if($this->parent->disable_typecast_read == false){
  397. $cast->queryResult($format="array_object", $data, $query["types"]);
  398. if($this->parent->print_result_cast == true){
  399. ob_start();
  400. echo "\nCAST, format = array_key_array\n";
  401. print_r($data);
  402. $out = ob_get_clean();
  403. BPM_debug::addToFile($out);
  404. }
  405. }
  406. if($data){
  407. $result = array();
  408. // If a single column name is passed as a string, use the more efficient
  409. // direct assignment algorithm to build a 1 level tree
  410. if( !is_array($ctrl["key_col"]) ){
  411. foreach($data as $row){
  412. $arr = array();
  413. // Convert row object into array
  414. foreach($row as $key => $value){
  415. $arr[$key] = $value;
  416. }
  417. // Insert row array into primary array as named key
  418. $result[$row->{$ctrl["key_col"]}] = $arr;
  419. }
  420. }
  421. // If an array of column names are passed, use the less efficient eval()
  422. // algorithm to build a n-level deep tree
  423. else {
  424. foreach($data as $row){
  425. // Since there is no functionality in PHP for creating a new array key
  426. // based on a name stored in a variable ( $$ variable variable syntax does
  427. // not work for multidimensional arrays), we have to build a string of PHP
  428. // code and use eval() to run it
  429. $eval_str = "\$result";
  430. foreach($ctrl["key_col"] as $keyname){
  431. $eval_str .= '["' . $row->{$keyname} . '"]';
  432. }
  433. $eval_str .= " = \$arr;";
  434. $arr = array();
  435. // Convert row object into array, skipping keys that are used as the
  436. // branch variables
  437. foreach($row as $key => $value){
  438. if( array_search($key, $ctrl["key_col"]) === false ){
  439. $arr[$key] = $value;
  440. }
  441. }
  442. // Run the PHP string we have built
  443. eval($eval_str);
  444. }
  445. }
  446. if($this->parent->print_result_formatted == true){
  447. ob_start();
  448. echo "\nFORMATTED, format = array_key_array\n";
  449. print_r($result);
  450. $out = ob_get_clean();
  451. BPM_debug::addToFile($out);
  452. }
  453. unset($data); // Reduce memory usage
  454. }
  455. } break;
  456. // ARRAY_KEY_ARRAY_GROUPED
  457. // =============================================================================
  458. //
  459. // Requires at least TWO column names, and columns not specified in $key_col are not
  460. // included in the results set. Returns results as an array of arrays^N-1, where the
  461. // array key names and heirarchy are set based on the contents of the $key_col array.
  462. // Results in the last db column specified in $key_col are grouped together in an
  463. // int-keyed array. The key name corresponds to the order in which a rows is returned
  464. // from the database and the value of each key is the column's value in the database
  465. // row. For a working example of how to use this result formatter, see the function
  466. // database_resultFormatters::test_array_key_array_grouped() in the database unit tests.
  467. //
  468. // EXAMPLE TABLE "test_table_2"
  469. // ===============================
  470. // col_1 | col_2 | col_3 | col_4
  471. // ===============================
  472. // 1 | red | dog | A
  473. // 2 | green| dog | B
  474. // 3 | green| dog | C
  475. // 4 | green| dog | D
  476. // 5 | blue | bird | A
  477. // 6 | black| bird | A
  478. // 7 | black| fish | A
  479. // 8 | black| fish | B
  480. //
  481. // UNIQUE KEY no_duplicates(col_2, col_3, col_4)
  482. //
  483. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"] = array("col_2, "col_3", "col_4")
  484. // NOTE: "col_1" is excluded because it is not specified in $ctrl["key_col"]
  485. // RESULT: array(
  486. // "dog" =>array(
  487. // "red"=> array("A"),
  488. // "green"=> array("B","C","D")
  489. // ),
  490. // "bird" =>array(
  491. // "blue"=> array("A"),
  492. // "black"=> array("A")
  493. // ),
  494. // "fish" =>array(
  495. // "black"=> array("A","B")
  496. // )
  497. // )
  498. case "array_key_array_grouped" : {
  499. $data = $this->parent->db->get_results($sql);
  500. if($this->parent->print_result_raw == true){
  501. ob_start();
  502. echo "RAW, format = array_key_array_grouped\n";
  503. print_r($data);
  504. $out = ob_get_clean();
  505. BPM_debug::addToFile($out);
  506. }
  507. if($this->parent->disable_typecast_read == false){
  508. $cast->queryResult($format="array_object", $data, $query["types"]);
  509. if($this->parent->print_result_cast == true){
  510. ob_start();
  511. echo "\nCAST, format = array_key_array_grouped\n";
  512. print_r($data);
  513. $out = ob_get_clean();
  514. BPM_debug::addToFile($out);
  515. }
  516. }
  517. if($data){
  518. $result = array();
  519. foreach($data as $row){
  520. // Since there is no functionality in PHP for creating a new array key
  521. // based on a name stored in a variable ( $$ variable variable syntax does
  522. // not work for multidimensional arrays), we have to build a string of PHP
  523. // code and use eval() to run it
  524. $eval_str = "\$result";
  525. $idx = sizeof($ctrl["key_col"]) - 1;
  526. $grouped_col = $ctrl["key_col"][$idx];
  527. foreach($ctrl["key_col"] as $keyname){
  528. if($keyname != $grouped_col){
  529. $eval_str .= '["' . $row->{$keyname} . '"]';
  530. }
  531. else {
  532. $eval_str .= '[]';
  533. }
  534. }
  535. $eval_str .= " = \$row->" . $grouped_col . ";";
  536. // Run the PHP string we have built
  537. eval($eval_str);
  538. }
  539. if($this->parent->print_result_formatted == true){
  540. ob_start();
  541. echo "\nFORMATTED, format = array_key_array_grouped\n";
  542. print_r($result);
  543. $out = ob_get_clean();
  544. BPM_debug::addToFile($out);
  545. }
  546. unset($data); // Reduce memory usage
  547. }
  548. } break;
  549. // ARRAY_KEY_ARRAY_TRUE
  550. // =============================================================================
  551. //
  552. // Returns results as an array of arrays^N-1, where the array key names and heirarchy
  553. // are set based on the contents of the $key_col array. Results in the last db column
  554. // specified in $key_col are grouped together in an result-keyed array where the key
  555. // name is the column's value in the database row and the key's value is (bool)true.
  556. // For a working example of how to use this result formatter, see the function
  557. // database_resultFormatters::test_array_key_array_true() in the database unit tests.
  558. //
  559. // EXAMPLE TABLE "test_table_2"
  560. // ===============================
  561. // col_1 | col_2 | col_3 | col_4
  562. // ===============================
  563. // 1 | red | dog | A
  564. // 2 | green| dog | B
  565. // 3 | green| dog | C
  566. // 4 | green| dog | D
  567. // 5 | blue | bird | A
  568. // 6 | black| bird | A
  569. // 7 | black| fish | A
  570. // 8 | black| fish | B
  571. //
  572. // UNIQUE KEY no_duplicates(col_2, col_3, col_4)
  573. //
  574. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"] = array("col_2, "col_3", "col_4")
  575. // NOTE: "col_1" is excluded because it is not specified in $ctrl["key_col"]
  576. // RESULT: array(
  577. // "dog" =>array(
  578. // "red"=> array("A"=>"true"),
  579. // "green"=> array("B"=>"true","C"=>"true","D"=>"true")
  580. // ),
  581. // "bird" =>array(
  582. // "blue"=> array("A"=>"true"),
  583. // "black"=> array("A"=>"true")
  584. // ),
  585. // "fish" =>array(
  586. // "black"=> array("A"=>"true","B"=>"true")
  587. // )
  588. // )
  589. case "array_key_array_true" : {
  590. $data = $this->parent->db->get_results($sql);
  591. if($this->parent->print_result_raw == true){
  592. ob_start();
  593. echo "RAW, format = array_key_array_true\n";
  594. print_r($data);
  595. $out = ob_get_clean();
  596. BPM_debug::addToFile($out);
  597. }
  598. if($this->parent->disable_typecast_read == false){
  599. $cast->queryResult($format="array_object", $data, $query["types"]);
  600. if($this->parent->print_result_cast == true){
  601. ob_start();
  602. echo "\nCAST, format = array_key_array_true\n";
  603. print_r($data);
  604. $out = ob_get_clean();
  605. BPM_debug::addToFile($out);
  606. }
  607. }
  608. if($data){
  609. $result = array();
  610. foreach($data as $row){
  611. // Since there is no functionality in PHP for creating a new array key
  612. // based on a name stored in a variable ( $$ variable variable syntax does
  613. // not work for multidimensional arrays), we have to build a string of PHP
  614. // code and use eval() to run it
  615. $eval_str = "\$result";
  616. foreach($ctrl["key_col"] as $keyname){
  617. $eval_str .= '["' . $row->{$keyname} . '"]';
  618. }
  619. $eval_str .= " = true;";
  620. // Run the PHP string we have built
  621. eval($eval_str);
  622. }
  623. if($this->parent->print_result_formatted == true){
  624. ob_start();
  625. echo "\nFORMATTED, format = array_key_array_true\n";
  626. print_r($result);
  627. $out = ob_get_clean();
  628. BPM_debug::addToFile($out);
  629. }
  630. unset($data); // Reduce memory usage
  631. }
  632. } break;
  633. // ARRAY_KEY_ARRAY_FALSE
  634. // =============================================================================
  635. //
  636. // Returns results as an array of arrays^N-1, where the array key names and heirarchy
  637. // are set based on the contents of the $key_col array. Results in the last db column
  638. // specified in $key_col are grouped together in an result-keyed array where the key
  639. // name is the column's value in the database row and the key's value is (bool)false.
  640. // For a working example of how to use this result formatter, see the function
  641. // database_resultFormatters::test_array_key_array_false() in the database unit tests.
  642. //
  643. // EXAMPLE TABLE "test_table_2"
  644. // ===============================
  645. // col_1 | col_2 | col_3 | col_4
  646. // ===============================
  647. // 1 | red | dog | A
  648. // 2 | green| dog | B
  649. // 3 | green| dog | C
  650. // 4 | green| dog | D
  651. // 5 | blue | bird | A
  652. // 6 | black| bird | A
  653. // 7 | black| fish | A
  654. // 8 | black| fish | B
  655. //
  656. // UNIQUE KEY no_duplicates(col_2, col_3, col_4)
  657. //
  658. // EXAMPLE: "SELECT * FROM test_table" + $ctrl["key_col"] = array("col_2, "col_3", "col_4")
  659. // NOTE: "col_1" is excluded because it is not specified in $ctrl["key_col"]
  660. // RESULT: array(
  661. // "dog" =>array(
  662. // "red"=> array("A"=>"false"),
  663. // "green"=> array("B"=>"false","C"=>"false","D"=>"false")
  664. // ),
  665. // "bird" =>array(
  666. // "blue"=> array("A"=>"false"),
  667. // "black"=> array("A"=>"false")
  668. // ),
  669. // "fish" =>array(
  670. // "black"=> array("A"=>"false","B"=>"false")
  671. // )
  672. // )
  673. case "array_key_array_false" : {
  674. $data = $this->parent->db->get_results($sql);
  675. if($this->parent->print_result_raw == true){
  676. ob_start();
  677. echo "RAW, format = array_key_array_false";
  678. print_r($data);
  679. $out = ob_get_clean();
  680. BPM_debug::addToFile($out);
  681. }
  682. if($this->parent->disable_typecast_read == false){
  683. $cast->queryResult($format="array_object", $data, $query["types"]);
  684. if($this->parent->print_result_cast == true){
  685. ob_start();
  686. echo "\nCAST, format = array_key_array_false";
  687. print_r($data);
  688. $out = ob_get_clean();
  689. BPM_debug::addToFile($out);
  690. }
  691. }
  692. if($data){
  693. $result = array();
  694. foreach($data as $row){
  695. // Since there is no functionality in PHP for creating a new array key
  696. // based on a name stored in a variable ( $$ variable variable syntax does
  697. // not work for multidimensional arrays), we have to build a string of PHP
  698. // code and use eval() to run it
  699. $eval_str = "\$result";
  700. foreach($ctrl["key_col"] as $keyname){
  701. $eval_str .= '["' . $row->{$keyname} . '"]';
  702. }
  703. $eval_str .= " = false;";
  704. // Run the PHP string we have built
  705. eval($eval_str);
  706. }
  707. if($this->parent->print_result_formatted == true){
  708. ob_start();
  709. echo "\nFORMATTED, format = array_key_array_false";
  710. print_r($result);
  711. $out = ob_get_clean();
  712. BPM_debug::addToFile($out);
  713. }
  714. unset($data); // Reduce memory usage
  715. }
  716. } break;
  717. // ARRAY_KEY_SINGLE
  718. // =============================================================================
  719. // Returns results as an array of ints or strings, where the array key names
  720. // are set based on the contents of a database column.
  721. //
  722. // EXAMPLE: "SELECT col_2, col_3 FROM test_table" + $ctrl["key_col"]="col_2", $ctrl["val_col"]="col_3"
  723. // RESULT: array(
  724. // "red"=>"dog",
  725. // "green"=>"cat",
  726. // "blue"=>"bird",
  727. // "black"=>"fish"
  728. // )
  729. case "array_key_single" : {
  730. $data = $this->parent->db->get_results($sql);
  731. if($this->parent->print_result_raw == true){
  732. ob_start();
  733. echo "RAW, format = array_key_single\n";
  734. print_r($data);
  735. $out = ob_get_clean();
  736. BPM_debug::addToFile($out);
  737. }
  738. if($this->parent->disable_typecast_read == false){
  739. $cast->queryResult($format="array_object", $data, $query["types"]);
  740. if($this->parent->print_result_cast == true){
  741. ob_start();
  742. echo "\nCAST, format = array_key_single\n";
  743. print_r($data);
  744. $out = ob_get_clean();
  745. BPM_debug::addToFile($out);
  746. }
  747. }
  748. if($data){
  749. $result = array();
  750. foreach($data as $row){
  751. $result[$row->{$ctrl["key_col"]}] = $row->{$ctrl["val_col"]};
  752. }
  753. if($this->parent->print_result_formatted == true){
  754. ob_start();
  755. echo "\nCAST, format = array_key_single\n";
  756. print_r($result);
  757. $out = ob_get_clean();
  758. BPM_debug::addToFile($out);
  759. }
  760. unset($data); // Reduce memory usage
  761. }
  762. } break;
  763. // ARRAY_OBJECT
  764. // =============================================================================
  765. // Returns results as an array of objects, where the primary array keys are
  766. // zero-indexed ints
  767. //
  768. // EXAMPLE: "SELECT * FROM test_table"
  769. // RESULT: array(
  770. // stdClass( "col_1"->1, "col_2"->"red", "col_3"->"dog", "col_4"->"big"),
  771. // stdClass( "col_1"->2, "col_2"->"green", "col_3"->"cat", "col_4"->"med"),
  772. // stdClass( "col_1"->3, "col_2"->"blue", "col_3"->"bird", "col_4"->"small"),
  773. // stdClass( "col_1"->4, "col_2"->"black", "col_3"->"fish", "col_4"->"tiny"),
  774. // )
  775. case "array_object" : {
  776. $result = $this->parent->db->get_results($sql);
  777. if($this->parent->print_result_raw == true){
  778. ob_start();
  779. echo "RAW, format = array_object\n";
  780. print_r($data);
  781. $out = ob_get_clean();
  782. BPM_debug::addToFile($out);
  783. }
  784. if($this->parent->disable_typecast_read == false){
  785. $cast->queryResult($format="array_object", $data, $query["types"]);
  786. if($this->parent->print_result_cast == true){
  787. ob_start();
  788. echo "\nCAST, format = array_object\n";
  789. print_r($data);
  790. $out = ob_get_clean();
  791. BPM_debug::addToFile($out);
  792. }
  793. }
  794. if($this->parent->print_result_formatted == true){
  795. ob_start();
  796. print_r($result);
  797. $out = ob_get_clean();
  798. BPM_debug::addToFile($out);
  799. }
  800. } break;
  801. // ARRAY_ARRAY
  802. // =============================================================================
  803. // Returns results as an array of arrays, where the primary array keys are
  804. // zero-indexed ints
  805. //
  806. // EXAMPLE: "SELECT * FROM test_table"
  807. // RESULT: array(
  808. // array( "col_1"=>1, "col_2"=>"red", "col_3"=>"dog", "col_4"=>"big"),
  809. // array( "col_1"=>2, "col_2"=>"green", "col_3"=>"cat", "col_4"=>"med"),
  810. // array( "col_1"=>3, "col_2"=>"blue", "col_3"=>"bird", "col_4"=>"small"),
  811. // array( "col_1"=>4, "col_2"=>"black", "col_3"=>"fish", "col_4"=>"tiny"),
  812. // )
  813. case "array_array" : {
  814. $data = $this->parent->db->get_results($sql);
  815. if($this->parent->print_result_raw == true){
  816. ob_start();
  817. echo "RAW, format = array_array\n";
  818. print_r($data);
  819. $out = ob_get_clean();
  820. BPM_debug::addToFile($out);
  821. }
  822. if($this->parent->disable_typecast_read == false){
  823. $cast->queryResult($format="array_object", $data, $query["types"]);
  824. if($this->parent->print_result_cast == true){
  825. ob_start();
  826. echo "\nCAST, format = array_array\n";
  827. print_r($data);
  828. $out = ob_get_clean();
  829. BPM_debug::addToFile($out);
  830. }
  831. }
  832. if($data){
  833. $result = array();
  834. foreach($data as $row){
  835. $arr = array();
  836. // Convert row object into array
  837. foreach($row as $key => $value){
  838. $arr[$key] = $value;
  839. }
  840. // Insert row array into primary array as unnamed key
  841. $result[] = $arr;
  842. }
  843. if($this->parent->print_result_formatted == true){
  844. ob_start();
  845. echo "\nFORMATTED, format = array_array\n";
  846. print_r($result);
  847. $out = ob_get_clean();
  848. BPM_debug::addToFile($out);
  849. }
  850. unset($data); // Reduce memory usage
  851. }
  852. } break;
  853. // (NULL)
  854. // =============================================================================
  855. // Runs a default SQL query. Returned result format depends on the query.
  856. default : {
  857. $result = $this->parent->db->query($sql);
  858. if($this->parent->print_result_raw == true){
  859. ob_start();
  860. echo "format = null\n";
  861. print_r($result);
  862. $out = ob_get_clean();
  863. BPM_debug::addToFile($out);
  864. }
  865. } break;
  866. } // END switch($ctrl["format"])
  867. // Check if the SQL server reported an error while running the query. Note that
  868. // we check directly with the SQL server using the database handle (dbh) instead
  869. // of checking $wpdb's internal error variable to avoid any possibility of
  870. // errors being cached in the $wpdb class
  871. // ===============================================================================
  872. $sql_error = mysql_error($this->parent->dbh);
  873. if($sql_error){
  874. throw new BPM_exception( array(
  875. 'numeric'=>2,
  876. 'text'=>"Error during query execution",
  877. 'data'=>array($sql, $sql_error),
  878. 'file'=>__FILE__, 'line'=>__LINE__, 'method'=>__METHOD__,
  879. 'child'=>null
  880. ));
  881. }
  882. else {
  883. return $result;
  884. }
  885. }
  886. } // End of class BPM_queryRunner
  887. ?>