PageRenderTime 55ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/sgl/assets/_core/php/examples/qcubed_query/expandasarray.php

http://logisticsouth.googlecode.com/
PHP | 114 lines | 101 code | 13 blank | 0 comment | 18 complexity | d2b3721ecb50902a9d6edd1224b567ed MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php require_once('../qcubed.inc.php'); ?>
  2. <?php require('../includes/header.inc.php'); ?>
  3. <div class="instructions">
  4. <h1 class="instruction_title">ExpandAsArray: Multiple Related Tables in One Swift Query</h1>
  5. You've certainly had to deal with some sort of hierarchical data in your
  6. database. Let's say you have a set of <b>Persons</b>; each person can be
  7. a manager for a <b>Project</b>. Each <b>Project</b> has one or more milestones.
  8. Oh, wait! And each <b>Person</b> has one or more <b>Addresses</b>.<br /><br />
  9. So, if you were to look at the schema subsection visually, it would look like this:<br />
  10. <img src="expandasarray_schema_diagram.png" /><br /><br />
  11. What if you need to display BOTH the project information, and the address
  12. information, for each of the people in your database? A standard approach
  13. would be to issue two queries - one for addresses, another one for projects;
  14. you'd then need to somehow merge the two arrays to be able to output the
  15. address and the projects of the same person at once. Pain..<br /><br />
  16. Well, no more pain. <b>ExpandAsArray</b> to your rescue. Note that this
  17. is a somewhat advanced topic - so if you're not comfortable with the
  18. concepts of <a href="../more_codegen/early_bind.php">QCubed Early Binding</a> and
  19. <a href="qqclause.php">QQ::Clauses</a>, read up on those first. <br /><br />
  20. We'll issue one mega-powerful query that will allow you to get BOTH the
  21. <b>Address</b> and the <b>Project</b> data (with the related info on
  22. the <b>Milestones</b> for each project) in one powerful sweep. Moreover,
  23. this will only execute a single query against your database backend.
  24. Essentially, what will happen here is you'll get an object and ALL
  25. types of related objects for it - something that SQL isn't really meant
  26. to do. Object-oriented databases would be an exit, but we love our
  27. relational systems too much, don't we? <br /><br />
  28. Here's that magical expression:<br />
  29. <div style="padding-left: 50px"><code>
  30. $arrPersons = Person::LoadAll(QQ::Clause(<br />
  31. &nbsp;&nbsp;&nbsp;QQ::ExpandAsArray(QQN::Person()->Address),<br />
  32. &nbsp;&nbsp;&nbsp;QQ::ExpandAsArray(QQN::Person()->ProjectAsManager),<br />
  33. &nbsp;&nbsp;&nbsp;QQ::ExpandAsArray(QQN::Person()->ProjectAsManager->Milestone)<br />
  34. ));
  35. </code></div><br />
  36. The resulting <b>$arrPersons</b> will be an array of objects of type
  37. <b>Person</b>. Each of those objects will have member variables called
  38. <b>_AddressArray</b> (array of <b>Address</b> objects) and <b>_ProjectAsManagerArray</b>
  39. (array of <b>Project</b> objects). Each of the <b>Project</b> objects will also
  40. have a member variable <b>_MilestoneArray</b>, containing an array of <b>Milestone</b>
  41. objects. It's then trivial to iterate through the <b>$arrPersons</b> to output all
  42. of that data - all the <b>Project</b> and <b>Address</b> is now neatly
  43. organized under each <b>Person</b>.<br /><br />
  44. NOTE: Be careful around the number of items in each of the tables that will
  45. be returned by the query that you execute. In the example above, the total
  46. number of rows returned from SQL in that one query is equal to:<br />
  47. <center><b>(Num of Persons) * (Num of Projects) * (Num of Milestones) *
  48. (Num of Addresses)</b></center><br />
  49. You can see how it can get out of hand quickly - and the performance gains
  50. you get out of issuing a single query can become a detriment instead, because
  51. of the amount of data that gets transfered from your database server to PHP.
  52. Thus, this approach only makes sense if you don't expect to have hundreds of
  53. items in each of the tables you're extracting the data from. Be sure to look
  54. at the SQL statement generated by QQuery, and try running it yourself, keeping
  55. the number of results in mind.
  56. </div>
  57. <h3>Projects and Addresses for each Person</h3>
  58. <?php
  59. QApplication::$Database[1]->EnableProfiling();
  60. $people = Person::LoadAll(
  61. QQ::Clause(
  62. QQ::ExpandAsArray(QQN::Person()->Address),
  63. QQ::ExpandAsArray(QQN::Person()->ProjectAsManager),
  64. QQ::ExpandAsArray(QQN::Person()->ProjectAsManager->Milestone)
  65. )
  66. );
  67. foreach ($people as $person) {
  68. echo "<b>" . $person->FirstName . " " . $person->LastName . "</b><br />";
  69. echo "Addresses: ";
  70. if (sizeof($person->_AddressArray) == 0) {
  71. echo "none";
  72. } else {
  73. foreach ($person->_AddressArray as $address) {
  74. echo $address->Street . "; ";
  75. }
  76. }
  77. echo "<br />";
  78. echo "Projects where this person is a project manager: ";
  79. if (sizeof($person->_ProjectAsManagerArray) == 0) {
  80. echo "none<br />";
  81. } else {
  82. echo "<br />";
  83. foreach($person->_ProjectAsManagerArray as $project) {
  84. echo $project->Name . " (milestones: ";
  85. if (sizeof($project->_MilestoneArray) == 0) {
  86. echo "none";
  87. } else {
  88. foreach ($project->_MilestoneArray as $milestone) {
  89. echo $milestone->Name . "; ";
  90. }
  91. }
  92. echo ")<br />";
  93. }
  94. }
  95. echo "<br />";
  96. }
  97. QApplication::$Database[1]->OutputProfiling();
  98. ?>
  99. <?php require('../includes/footer.inc.php'); ?>