Changeset 429
- Timestamp:
- 11/07/07 12:07:24 (1 year ago)
- Files:
-
- branches/kaste/framework/lib/Ak.php (modified) (1 diff)
- branches/kaste/framework/lib/AkActiveRecord.php (modified) (3 diffs)
- branches/kaste/framework/lib/AkActiveRecord/AkAssociatedActiveRecord.php (modified) (7 diffs)
- branches/kaste/framework/lib/AkActiveRecord/AkDbAdapter.php (modified) (1 diff)
- branches/kaste/framework/lib/AkActiveRecord/AkDbAdapter_mysql.php (modified) (1 diff)
- branches/kaste/framework/lib/AkActiveRecord/AkHasOne.php (modified) (2 diffs)
- branches/kaste/framework/test/unit/lib/AkActiveRecord/AkDbAdapter.php (modified) (2 diffs)
- branches/kaste/framework/test/unit/lib/AkActiveRecord/_AkActiveRecord_2.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/kaste/framework/lib/Ak.php
r419 r429 67 67 if (empty($dsn) || !is_array($dsn)) $dsn = array(); 68 68 return AkDbAdapter::getConnection($dsn); 69 } 70 71 /** 72 * @param string $message 73 * @param [OPTIONAL] $fatal triggers even in production-mode 74 */ 75 function DeprecateWarning($message,$fatal=false) 76 { 77 if (!$fatal && AK_ENVIRONMENT == 'production') return; 78 if (is_array($message)){ 79 //$args = func_get_args(); 80 //$message = array_shift($message); 81 trigger_error(Ak::t("DEPRECATED WARNING: ".array_shift($message),$message), E_USER_NOTICE); 82 } else 83 trigger_error(Ak::t("DEPRECATED WARNING: ".$message), E_USER_NOTICE); 69 84 } 70 85 branches/kaste/framework/lib/AkActiveRecord.php
r427 r429 987 987 988 988 if((!empty($options['include']) && $this->hasAssociations())){ 989 $result =& $this->findWithAssociations($options , $limit, $offset);989 $result =& $this->findWithAssociations($options); 990 990 }else{ 991 $result =& $this->findBySql($sql , $limit, $offset);991 $result =& $this->findBySql($sql); 992 992 } 993 993 … … 1130 1130 function &findBySql($sql, $limit = null, $offset = null, $bindings = null) 1131 1131 { 1132 if ($limit || $offset){ 1133 Ak::DeprecateWarning("You're calling AR::findBySql with \$limit or \$offset parameters. This has been deprecated."); 1134 $this->_db->addLimitAndOffset($sql, array('limit'=>$limit,'offset'=>$offset)); 1135 } 1132 1136 if(!isset($this->_activeRecordHasBeenInstantiated)){ 1133 1137 return Ak::handleStaticCall(); 1134 1138 } 1135 if(is_array($sql)){ 1136 $sql_query = array_shift($sql); 1137 $bindings = is_array($sql) && count($sql) > 0 ? $sql : array($sql); 1138 $sql = $sql_query; 1139 } 1140 //$this->setConnection(); 1139 1140 $objects = array(); 1141 $results = $this->_db->sqlexecute ($sql,'selecting'); 1142 if (!$results) return $objects; 1141 1143 1142 AK_LOG_EVENTS ? $this->_startSqlBlockLog() : null; 1143 1144 $objects = array(); 1145 if(is_integer($limit)){ 1146 if(is_integer($offset)){ 1147 $results = !empty($bindings) ? $this->_db->SelectLimit($sql, $limit, $offset, $bindings) : $this->_db->SelectLimit($sql, $limit, $offset); 1148 }else { 1149 $results = !empty($bindings) ? $this->_db->SelectLimit($sql, $limit, -1, $bindings) : $this->_db->SelectLimit($sql, $limit); 1150 } 1151 }else{ 1152 $results = !empty($bindings) ? $this->_db->Execute($sql, $bindings) : $this->_db->Execute($sql); 1153 } 1154 1155 AK_LOG_EVENTS ? $this->_endSqlBlockLog() : null; 1156 1157 if(!$results){ 1158 AK_DEBUG ? trigger_error($this->_db->ErrorMsg(), E_USER_NOTICE) : null; 1159 }else{ 1160 $objects = array(); 1161 while ($record = $results->FetchRow()) { 1162 $objects[] =& $this->instantiate($this->getOnlyAvailableAtrributes($record), false); 1163 } 1164 } 1165 1144 while ($record = $results->FetchRow()) { 1145 $objects[] =& $this->instantiate($this->getOnlyAvailableAtrributes($record), false); 1146 } 1166 1147 return $objects; 1167 1148 } … … 1375 1356 1376 1357 $sql .= !empty($options['order']) ? ' ORDER BY '.$options['order'] : ''; 1358 1359 $this->_db->addLimitAndOffset($sql,$options); 1377 1360 1378 1361 return $sql; branches/kaste/framework/lib/AkActiveRecord/AkAssociatedActiveRecord.php
r333 r429 229 229 } 230 230 231 function &findWithAssociations($options , $limit = null, $offset = null)231 function &findWithAssociations($options) 232 232 { 233 233 $result = false; … … 273 273 274 274 $sql = trim($this->constructFinderSqlWithAssociations($options)); 275 $sql = substr($sql, -5) == 'AND =' ? substr($sql, 0,-5) : $sql;275 //$sql = substr($sql, -5) == 'AND =' ? substr($sql, 0,-5) : $sql; // never called! 276 276 277 277 if(!empty($options['bind']) && is_array($options['bind']) && strstr($sql,'?')){ 278 278 $sql = array_merge(array($sql),$options['bind']); 279 279 } 280 $result =& $this->_findBySqlWithAssociations($sql, $ limit, $offset, $options['include'], empty($options['virtual_limit']) ? false : $options['virtual_limit']);280 $result =& $this->_findBySqlWithAssociations($sql, $options['include'], empty($options['virtual_limit']) ? false : $options['virtual_limit']); 281 281 282 282 return $result; … … 305 305 function constructFinderSqlWithAssociations($options, $include_owner_as_selection = true) 306 306 { 307 $sql = 'SELECT '; 307 308 $selection = ''; 308 309 if($include_owner_as_selection){ … … 310 311 $selection .= '__owner.'.$column_name.' AS __owner_'.$column_name.', '; 311 312 } 312 313 $s ql = 'SELECT '.trim($selection.@$options['selection'], ', ').' '.314 'FROM '.$this->getTableName().' AS __owner '.315 (!empty($options['joins']) ? $options['joins'].' ' : '');316 }else{317 $sql = 'SELECT '.$options['selection'].'.* '.318 'FROM '.$options['selection'].' '.319 (!empty($options['joins']) ? $options['joins'].' ' : '');320 }313 $selection .= @$options['selection'].' '; 314 $selection = trim($selection,', ').' '; // never used by the unit tests 315 }else{ 316 // used only by HasOne::findAssociated 317 $selection .= $options['selection'].'.* '; 318 } 319 $sql .= $selection; 320 $sql .= 'FROM '.($include_owner_as_selection ? $this->getTableName().' AS __owner ' : $options['selection'].' '); 321 $sql .= (!empty($options['joins']) ? $options['joins'].' ' : ''); 321 322 322 323 empty($options['conditions']) ? null : $this->addConditions($sql, $options['conditions']); … … 327 328 } 328 329 $sql .= !empty($options['order']) ? ' ORDER BY '.$options['order'] : ''; 330 331 $this->_db->addLimitAndOffset($sql,$options); 329 332 return $sql; 330 333 } … … 334 337 * @todo Refactor in order to increase performance of associated inclussions 335 338 */ 336 function &_findBySqlWithAssociations($sql, $limit = null, $offset = null, $included_associations = array(), $virtual_limit = false) 337 { 338 if(is_array($sql)){ 339 $sql_query = array_shift($sql); 340 $bindings = is_array($sql) && count($sql) > 0 ? $sql : array($sql); 341 $sql = $sql_query; 342 } 343 $this->setConnection(); 344 345 AK_LOG_EVENTS ? $this->_startSqlBlockLog() : null; 346 339 function &_findBySqlWithAssociations($sql, $included_associations = array(), $virtual_limit = false) 340 { 347 341 $objects = array(); 342 $results = $this->_db->sqlexecute ($sql,'find with associations'); 343 if (!$results) return $objects; 344 345 $i = 0; 346 $associated_ids = $this->getAssociatedIds(); 347 $number_of_associates = count($associated_ids); 348 348 $_included_results = array(); // Used only in conjuntion with virtual limits for doing find('first',...include'=>... 349 if(is_integer($limit)){ 350 if(is_integer($offset)){ 351 $results = !empty($bindings) ? 352 $this->_db->SelectLimit($sql, $limit, $offset, $bindings) : 353 $this->_db->SelectLimit($sql, $limit, $offset); 354 }else { 355 $results = !empty($bindings) ? 356 $this->_db->SelectLimit($sql, $limit, -1, $bindings) : 357 $this->_db->SelectLimit($sql, $limit); 358 } 359 }else{ 360 $results = !empty($bindings) ? 361 $this->_db->Execute($sql, $bindings) : 362 $this->_db->Execute($sql); 363 } 364 365 AK_LOG_EVENTS ? $this->_endSqlBlockLog() : null; 366 367 if(!$results && AK_DEBUG){ 368 trigger_error($this->_db->ErrorMsg(), E_USER_NOTICE); 369 }else{ 370 $objects = array(); 371 $i = 0; 372 $associated_ids = $this->getAssociatedIds(); 373 $number_of_associates = count($associated_ids); 374 $object_associates_details = array(); 375 376 $ids = array(); 377 while ($record = $results->FetchRow()) { 378 $this_item_attributes = array(); 379 $associated_items = array(); 380 foreach ($record as $column=>$value){ 381 if(!is_numeric($column)){ 382 if(substr($column,0,8) == '__owner_'){ 383 $attribute_name = substr($column,8); 384 $this_item_attributes[$attribute_name] = $value; 385 }elseif(preg_match('/^_('.join('|',$associated_ids).')_(.+)/',$column, $match)){ 386 $associated_items[$match[1]][$match[2]] = $value; 387 } 349 $object_associates_details = array(); 350 $ids = array(); 351 while ($record = $results->FetchRow()) { 352 $this_item_attributes = array(); 353 $associated_items = array(); 354 foreach ($record as $column=>$value){ 355 if(!is_numeric($column)){ 356 if(substr($column,0,8) == '__owner_'){ 357 $attribute_name = substr($column,8); 358 $this_item_attributes[$attribute_name] = $value; 359 }elseif(preg_match('/^_('.join('|',$associated_ids).')_(.+)/',$column, $match)){ 360 $associated_items[$match[1]][$match[2]] = $value; 388 361 } 389 362 } 390 391 392 // We need to keep a pointer to unique parent elements in order to add associates to the first loaded item 393 $e = null; 394 $object_id = $this_item_attributes[$this->getPrimaryKey()]; 395 396 if(!empty($virtual_limit)){ 397 $_included_results[$object_id] = $object_id; 398 if(count($_included_results) > $virtual_limit * $number_of_associates){ 399 continue; 400 } 401 } 402 403 if(!isset($ids[$object_id])){ 404 $ids[$object_id] = $i; 405 $attributes_for_instantation = $this->getOnlyAvailableAtrributes($this_item_attributes); 406 $attributes_for_instantation['load_associations'] = true; 407 $objects[$i] =& $this->instantiate($attributes_for_instantation, false); 408 }else{ 409 $e = $i; 410 $i = $ids[$object_id]; 411 } 412 413 foreach ($associated_items as $association_id=>$attributes){ 414 if(count(array_diff($attributes, array(''))) > 0){ 415 $object_associates_details[$i][$association_id][md5(serialize($attributes))] = $attributes; 416 } 417 } 418 419 $i = !is_null($e) ? $e : $i+1; 420 } 363 } 364 365 // We need to keep a pointer to unique parent elements in order to add associates to the first loaded item 366 $e = null; 367 $object_id = $this_item_attributes[$this->getPrimaryKey()]; 368 369 if(!empty($virtual_limit)){ 370 $_included_results[$object_id] = $object_id; 371 if(count($_included_results) > $virtual_limit * $number_of_associates){ 372 continue; 373 } 374 } 375 376 if(!isset($ids[$object_id])){ 377 $ids[$object_id] = $i; 378 $attributes_for_instantation = $this->getOnlyAvailableAtrributes($this_item_attributes); 379 $attributes_for_instantation['load_associations'] = true; 380 $objects[$i] =& $this->instantiate($attributes_for_instantation, false); 381 }else{ 382 $e = $i; 383 $i = $ids[$object_id]; 384 } 385 386 foreach ($associated_items as $association_id=>$attributes){ 387 if(count(array_diff($attributes, array(''))) > 0){ 388 $object_associates_details[$i][$association_id][md5(serialize($attributes))] = $attributes; 389 } 390 } 391 392 $i = !is_null($e) ? $e : $i+1; 421 393 } 422 394 … … 439 411 } 440 412 441 if(!empty($objects)){ 442 $result =& $objects; 443 }else{ 444 $result = false; 445 } 446 413 $result =& $objects; 447 414 return $result; 448 415 } branches/kaste/framework/lib/AkActiveRecord/AkDbAdapter.php
r428 r429 183 183 } 184 184 185 function addLimitAndOffset(&$sql,$options) 186 { 187 if (isset($options['limit']) && $limit = $options['limit']){ 188 $sql .= " LIMIT $limit"; 189 if (isset($options['offset']) && $offset = $options['offset']){ 190 $sql .= " OFFSET $offset"; 191 } 192 } 193 return $sql; 194 } 195 185 196 /* DATABASE STATEMENTS - CRUD */ 186 197 branches/kaste/framework/lib/AkActiveRecord/AkDbAdapter_mysql.php
r416 r429 43 43 return 'mysql'; 44 44 } 45 46 function addLimitAndOffset(&$sql,$options) 47 { 48 if (isset($options['limit']) && $limit = $options['limit']){ 49 if (isset($options['offset']) && $offset = $options['offset']) 50 $sql .= " LIMIT $offset, $limit"; 51 else 52 $sql .= " LIMIT $limit"; 53 } 54 return $sql; 55 } 56 45 57 } 46 58 ?> branches/kaste/framework/lib/AkActiveRecord/AkHasOne.php
r407 r429 243 243 function &findAssociated($association_id) 244 244 { 245 $result = false; 246 if(!$this->Owner->getId()){ 247 return $result; 248 } 245 if(!$this->Owner->getId()) return false; 249 246 250 247 if(empty($this->Owner->$association_id->__activeRecordObject)){ … … 260 257 'order' => trim($this->Owner->$association_id->_addTableAliasesToAssociatedSql($table_name, $this->Owner->$association_id->getAssociationOption('order'))) 261 258 ); 262 263 if($results =& $this->Owner->$association_id->findBySql($this->Owner->constructFinderSqlWithAssociations($finder_options, false),1)){ 259 260 // TODO: we will use a select statement later 261 $sql = $this->Owner->constructFinderSqlWithAssociations($finder_options, false);//.' LIMIT 1'; 262 if($results =& $this->Owner->$association_id->findBySql($sql)){ 264 263 $result =& $results[0]; 265 264 } branches/kaste/framework/test/unit/lib/AkActiveRecord/AkDbAdapter.php
r428 r429 25 25 function test_execute_should_handle_bindings() 26 26 { 27 $db =& AkDbAdapter::getConnection(null,false);27 $db =& new AkDbAdapter(array()); 28 28 Mock::generate('ADOConnection'); 29 29 $connection =& new MockADOConnection(); … … 35 35 $db->sqlexecute(array('SELECT * FROM articles WHERE id=?',1)); 36 36 } 37 38 function test_should_add_limit_and_offset_mysql_style() 39 { 40 $mysql_db =& AkDbAdapter::getConnection(array('type'=>'mysql'),false); 41 $sql = 'SELECT * FROM articles'; 42 $mysql_db->addLimitAndOffset($sql,array('limit'=>2,'offset'=>10)); 43 $this->assertEqual('SELECT * FROM articles LIMIT 10, 2',$sql); 44 45 $sql = 'SELECT * FROM articles'; 46 $mysql_db->addLimitAndOffset($sql,array('offset'=>10)); 47 $this->assertEqual('SELECT * FROM articles',$sql); 48 49 $sql = 'SELECT * FROM articles'; 50 $mysql_db->addLimitAndOffset($sql,array('limit'=>10)); 51 $this->assertEqual('SELECT * FROM articles LIMIT 10',$sql); 52 } 53 54 function test_should_add_limit_and_offset_common_style() 55 { 56 $mysql_db =& AkDbAdapter::getConnection(array('type'=>'postgre'),false); 57 $sql = 'SELECT * FROM articles'; 58 $mysql_db->addLimitAndOffset($sql,array('limit'=>2,'offset'=>10)); 59 $this->assertEqual('SELECT * FROM articles LIMIT 2 OFFSET 10',$sql); 60 61 $sql = 'SELECT * FROM articles'; 62 $mysql_db->addLimitAndOffset($sql,array('offset'=>10)); 63 $this->assertEqual('SELECT * FROM articles',$sql); 64 65 $sql = 'SELECT * FROM articles'; 66 $mysql_db->addLimitAndOffset($sql,array('limit'=>10)); 67 $this->assertEqual('SELECT * FROM articles LIMIT 10',$sql); 68 } 37 69 } 38 70 branches/kaste/framework/test/unit/lib/AkActiveRecord/_AkActiveRecord_2.php
r407 r429 449 449 $FoundUsers = $Users->findBySql("SELECT * FROM ak_test_users",6); 450 450 $this->assertEqual(count($FoundUsers), 6); 451 $this->assertErrorPattern("/DEPRECATED WARNING.*findBySql.*/"); 451 452 452 453 $FoundUsers = $Users->findBySql("SELECT * FROM ak_test_users",6,6); 453 454 $this->assertEqual(count($FoundUsers), 3); 454 455 $this->assertErrorPattern("/DEPRECATED WARNING.*findBySql.*/"); 456 457 $FoundUsers = $Users->findBySql("SELECT * FROM ak_test_users WHERE iad=123"); 458 $this->assertEqual(count($FoundUsers), 0); 459 $this->assertError(); 460 455 461 } 456 462
