Changeset 3110
- Timestamp:
- 04/13/08 09:14:54 (3 months ago)
- Files:
-
- trunk/Solar/Sql/Model.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Solar/Sql/Model.php
r3105 r3110 616 616 $col = preg_replace('/([a-z])([A-Z])/', '$1_$2', $col); 617 617 $col = strtolower($col); 618 $where[" $col = ?"] = $params[$key];618 $where["{$this->_model_name}.$col = ?"] = $params[$key]; 619 619 } 620 620 … … 699 699 public function fetchAll($params = array()) 700 700 { 701 // setup701 // prepare 702 702 $params = $this->fixSelectParams($params); 703 $select = $this->newSelect($params['eager']); 704 705 // build 706 $select->distinct($params['distinct']) 707 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 708 ->multiWhere($params['where']) 709 ->group($params['group']) 710 ->having($params['having']) 711 ->order($params['order']) 712 ->setPaging($params['paging']) 713 ->limitPage($params['page']) 714 ->bind($params['bind']); 715 716 // fetch all with eager loading 717 return $this->_fetchAll($select, $params); 718 } 719 720 /** 721 * 722 * Support method for fetchAll() to add eager related records. 723 * 724 * @param Solar_Sql_Select $select The select object for fetching. 725 * 726 * @param array $params The original params passed to fetchAll(). In 727 * general, only needed for the 'eager' key. 728 * 729 * @return mixed Solar_Sql_Model_Collection of found records, or an empty 730 * array if no records were found. 731 * 732 */ 733 protected function _fetchAll($select, $params) 734 { 735 $data = $select->fetchAll(); 736 if ($data) { 737 $coll = $this->newCollection($data); 738 foreach ((array) $params['eager'] as $name) { 739 $related = $this->getRelated($name); 740 if ($related->type == 'has_many') { 741 $data = $this->fetchRelatedArray($select, $name); 742 $coll->loadRelated($name, $data); 743 } 744 } 745 746 // if we're doing "count_pages", add pager info to the collection 747 if ($params['count_pages']) { 748 $this->_setCollectionPagerInfo($coll, $params); 749 } 750 751 // done 752 return $coll; 753 } else { 703 $select = $this->newSelect($params); 704 705 // fetch 706 $result = $select->fetchAll(); 707 if (! $result) { 754 708 return array(); 755 709 } 710 711 // create a collection from the result 712 $coll = $this->newCollection($result); 713 714 // add has-many eager data to the collection 715 foreach ((array) $params['eager'] as $name) { 716 $related = $this->getRelated($name); 717 if ($related->type == 'has_many') { 718 $result = $this->fetchRelatedArray($select, $name); 719 $coll->loadRelated($name, $result); 720 } 721 } 722 723 // add pager-info to the collection 724 if ($params['count_pages']) { 725 $this->_setCollectionPagerInfo($coll, $params); 726 } 727 728 // done 729 return $coll; 756 730 } 757 731 … … 797 771 public function fetchAssoc($params = array()) 798 772 { 799 // setup773 // prepare 800 774 $params = $this->fixSelectParams($params); 801 $select = $this->newSelect($params['eager']); 802 803 // build 804 $select->distinct($params['distinct']) 805 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 806 ->multiWhere($params['where']) 807 ->group($params['group']) 808 ->having($params['having']) 809 ->order($params['order']) 810 ->setPaging($params['paging']) 811 ->limitPage($params['page']) 812 ->bind($params['bind']); 775 $select = $this->newSelect($params); 813 776 814 777 // fetch 815 return $this->_fetchAssoc($select, $params); 816 } 817 818 /** 819 * 820 * Support method for fetchAssoc() to add eager related records. 821 * 822 * @param Solar_Sql_Select $select The select object for fetching. 823 * 824 * @param array $params The original params passed to fetchAll(). In 825 * general, only needed for the 'eager' key. 826 * 827 * @return mixed Solar_Sql_Model_Collection of found records, or an empty 828 * array if no records were found. 829 * 830 */ 831 protected function _fetchAssoc($select, $params) 832 { 833 $data = $select->fetchAssoc(); 834 if ($data) { 835 $coll = $this->newCollection($data); 836 foreach ((array) $params['eager'] as $name) { 837 $related = $this->getRelated($name); 838 if ($related->type == 'has_many') { 839 $data = $this->fetchRelatedArray($select, $name); 840 $coll->loadRelated($name, $data); 841 } 842 } 843 844 // if we're doing "count_pages", add pager info to the collection 845 if ($params['count_pages']) { 846 $this->_setCollectionPagerInfo($coll, $params); 847 } 848 849 // done 850 return $coll; 851 } else { 778 $result = $select->fetchAssoc(); 779 if (! $result) { 852 780 return array(); 853 781 } 782 783 // create a collection from the result 784 $coll = $this->newCollection($result); 785 786 // add has-many eager data to the collection 787 foreach ((array) $params['eager'] as $name) { 788 $related = $this->getRelated($name); 789 if ($related->type == 'has_many') { 790 $result = $this->fetchRelatedArray($select, $name); 791 $coll->loadRelated($name, $result); 792 } 793 } 794 795 // add pager-info to the collection 796 if ($params['count_pages']) { 797 $this->_setCollectionPagerInfo($coll, $params); 798 } 799 800 // done 801 return $coll; 854 802 } 855 803 … … 870 818 { 871 819 $total = $this->countPages($params); 872 $ begin = ($params['page'] - 1) * $params['paging'] + 1;820 $start = ($params['page'] - 1) * $params['paging']; 873 821 $coll->setPagerInfo(array( 874 822 'count' => $total['count'], … … 876 824 'paging' => $params['paging'], 877 825 'page' => $params['page'], 878 'begin' => $ begin,879 'end' => $ begin+ $coll->count(),826 'begin' => $start + 1, 827 'end' => $start + $coll->count(), 880 828 )); 881 829 } … … 917 865 public function fetchOne($params = array()) 918 866 { 919 // setup867 // prepare 920 868 $params = $this->fixSelectParams($params); 921 $select = $this->newSelect($params['eager']); 922 923 // build 924 $select->distinct($params['distinct']) 925 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 926 ->multiWhere($params['where']) 927 ->group($params['group']) 928 ->having($params['having']) 929 ->order($params['order']) 930 ->bind($params['bind']); 869 $select = $this->newSelect($params); 931 870 932 871 // fetch 933 $ data= $select->fetchOne();934 if (! $ data) {872 $result = $select->fetchOne(); 873 if (! $result) { 935 874 return null; 936 875 } 937 876 938 877 // get the main record, which sets the belongs_to/has_one data 939 $record = $this->newRecord($ data);878 $record = $this->newRecord($result); 940 879 941 880 // get related data from each eager has_many relationship … … 992 931 public function fetchCol($params = array()) 993 932 { 994 // setup933 // prepare 995 934 $params = $this->fixSelectParams($params); 996 $select = $this->newSelect($params['eager']); 997 998 // build 999 $select->distinct($params['distinct']) 1000 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 1001 ->multiWhere($params['where']) 1002 ->group($params['group']) 1003 ->having($params['having']) 1004 ->order($params['order']) 1005 ->setPaging($params['paging']) 1006 ->limitPage($params['page']) 1007 ->bind($params['bind']); 935 $select = $this->newSelect($params); 1008 936 1009 937 // fetch 1010 $ data= $select->fetchCol();1011 if ($ data) {1012 return $ data;938 $result = $select->fetchCol(); 939 if ($result) { 940 return $result; 1013 941 } else { 1014 942 return array(); … … 1057 985 public function fetchPairs($params = array()) 1058 986 { 1059 // setup987 // prepare 1060 988 $params = $this->fixSelectParams($params); 1061 $select = $this->newSelect($params['eager']); 1062 1063 // build 1064 $select->distinct($params['distinct']) 1065 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 1066 ->multiWhere($params['where']) 1067 ->group($params['group']) 1068 ->having($params['having']) 1069 ->order($params['order']) 1070 ->setPaging($params['paging']) 1071 ->limitPage($params['page']) 1072 ->bind($params['bind']); 989 $select = $this->newSelect($params); 1073 990 1074 991 // fetch 1075 $ data= $select->fetchPairs();1076 if ($ data) {1077 return $ data;992 $result = $select->fetchPairs(); 993 if ($result) { 994 return $result; 1078 995 } else { 1079 996 return array(); … … 1122 1039 public function fetchValue($params = array()) 1123 1040 { 1124 // setup1125 1041 $params = $this->fixSelectParams($params); 1126 $select = $this->newSelect($params['eager']); 1127 $col = current($params['cols']); 1128 1129 // build 1130 $select->distinct($params['distinct']) 1131 ->from("{$this->_table_name} AS {$this->_model_name}", $col) 1132 ->multiWhere($params['where']) 1133 ->group($params['group']) 1134 ->having($params['having']) 1135 ->order($params['order']) 1136 ->setPaging($params['paging']) 1137 ->limitPage($params['page']) 1138 ->bind($params['bind']); 1139 1140 // fetch 1042 $select = $this->newSelect($params); 1141 1043 return $select->fetchValue(); 1142 1044 } … … 1202 1104 public function countPages($params = null) 1203 1105 { 1106 // fix up the parameters 1204 1107 $params = $this->fixSelectParams($params); 1205 1108 1206 $select = $this->newSelect(); 1207 $select->distinct($params['distinct']) 1208 ->from("{$this->_table_name} AS {$this->_model_name}") 1209 ->multiWhere($params['where']) 1210 ->group($params['group']) 1211 ->having($params['having']) 1212 ->setPaging($this->_paging) 1213 ->bind($params['bind']); 1214 1109 // remove the 'eager' param for now, so we don't get the column- 1110 // based eager joins. 1111 $eager = (array) $params['eager']; 1112 $params['eager'] = array(); 1113 1114 // get the base select 1115 $select = $this->newSelect($params); 1116 1117 // add count-based eager joins 1118 foreach ($eager as $name) { 1119 $related = $this->getRelated($name); 1120 $related->modSelectCountPages($select); 1121 } 1122 1123 // done, count on the primary column 1215 1124 $col = "{$this->_model_name}.{$this->_primary_col}"; 1216 1217 1125 return $select->countPages($col); 1218 1126 } … … 1272 1180 1273 1181 if (empty($params['distinct'])) { 1274 $params['distinct'] = false; 1275 } 1276 1182 $params['distinct'] = null; 1183 } 1184 1185 // if we have columns, make sure they're unique 1186 if (! empty($params['cols'])) { 1187 $params['cols'] = array_unique((array) $params['cols']); 1188 } 1189 1190 // even after uniqing, cols might still be empty 1277 1191 if (empty($params['cols'])) { 1278 1192 $params['cols'] = array_keys($this->_table_cols); 1279 1193 } 1280 1194 1195 // if we have eager values, make sure they're unique 1196 if (! empty($params['eager'])) { 1197 $params['eager'] = array_unique((array) $params['eager']); 1198 } 1199 1200 // even after uniqing, the eager values might still be empty 1281 1201 if (empty($params['eager'])) { 1282 1202 $params['eager'] = null; … … 1323 1243 * injected automatically, and with eager "to-one" associations joined. 1324 1244 * 1325 * @param array $ eager An array of to-one relationship names to eager-1326 * load with LEFT JOIN clauses.1245 * @param array $params An array of SELECT parameters (esp. the 'eager' 1246 * param). 1327 1247 * 1328 1248 * @return Solar_Sql_Select 1329 1249 * 1330 1250 */ 1331 public function newSelect($ eager = null)1251 public function newSelect($params) 1332 1252 { 1333 1253 // get the select object … … 1337 1257 ); 1338 1258 1339 // add eager has_one/belongs_to joins 1340 foreach ((array) $eager as $name) { 1341 1342 // get the relationship options 1259 // modify the select to add eager joins 1260 foreach ((array) $params['eager'] as $name) { 1343 1261 $related = $this->getRelated($name); 1344 1345 // only process eager to-one associations at this point 1346 if ($related->type == 'has_many') { 1347 continue; 1348 } 1349 1350 // build column names as "name__col" so that we can extract the 1351 // the related data later. 1352 $cols = array(); 1353 foreach ($related->cols as $col) { 1354 $cols[] = "$col AS {$name}__$col"; 1355 } 1356 1357 // primary-key join condition on foreign table 1358 // local.id = foreign_alias.local_id 1359 $cond = "{$this->_model_name}.{$related->native_col} = " 1360 . "{$related->foreign_alias}.{$related->foreign_col}"; 1361 1362 // add the join 1363 $select->leftJoin( 1364 "{$related->foreign_table} AS {$related->foreign_alias}", 1365 $cond, 1366 $cols 1367 ); 1368 1369 // inheritance for foreign model 1370 if ($related->foreign_inherit_col) { 1371 $select->where( 1372 "{$related->foreign_alias}.{$related->foreign_inherit_col} = ?", 1373 $related->foreign_inherit_val 1374 ); 1375 1376 } 1377 1378 // added where conditions for the join 1379 $select->multiWhere($related->where); 1262 $related->modSelectEager($select); 1380 1263 } 1381 1264 … … 1387 1270 ); 1388 1271 } 1272 1273 // all the other pieces 1274 $select->distinct($params['distinct']) 1275 ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols']) 1276 ->multiWhere($params['where']) 1277 ->group($params['group']) 1278 ->multiHaving($params['having']) 1279 ->order($params['order']) 1280 ->setPaging($params['paging']) 1281 ->limitPage($params['page']) 1282 ->bind($params['bind']); 1389 1283 1390 1284 // done! … … 1647 1541 // no exception thrown, so it must have worked. 1648 1542 // if there was an autoincrement column, set its value in the data. 1649 $id = $this->_sql->lastInsertId($this->_table_name, $key);1650 1543 foreach ($this->_table_cols as $key => $val) { 1651 1544 if ($val['autoinc']) { 1652 1545 // set the value and leave the loop (should be only one) 1653 $data[$key] = $id; 1654 if ($spec instanceof Solar_Sql_Model_Record) { 1655 $spec->$key = $id; 1656 } 1546 $data[$key] = $this->_sql->lastInsertId($this->_table_name, $key); 1657 1547 break; 1658 1548 } … … 1661 1551 // refresh the table data in the record 1662 1552 if ($spec instanceof Solar_Sql_Model_Record) { 1553 // set the primary column so refresh will work 1554 $key = $this->_primary_col; 1555 $spec->$key = $data[$key]; 1556 // now refresh it 1663 1557 $spec->refresh(); 1664 1558 $spec->setStatus('inserted');
