예제 #1
0
 /**
  * Find records in the database.
  *
  * Finding by the primary key:
  *
  * <code>
  * # queries for the model with id=123
  * YourModel::find(123);
  *
  * # queries for model with id in(1,2,3)
  * YourModel::find(1,2,3);
  *
  * # finding by pk accepts an options array
  * YourModel::find(123,array('order' => 'name desc'));
  * </code>
  *
  * Finding by using a conditions array:
  *
  * <code>
  * YourModel::find('first', array('conditions' => array('name=?','Tito'),
  *   'order' => 'name asc'))
  * YourModel::find('all', array('conditions' => 'amount > 3.14159265'));
  * YourModel::find('all', array('conditions' => array('id in(?)', array(1,2,3))));
  * </code>
  *
  * Finding by using a hash:
  *
  * <code>
  * YourModel::find(array('name' => 'Tito', 'id' => 1));
  * YourModel::find('first',array('name' => 'Tito', 'id' => 1));
  * YourModel::find('all',array('name' => 'Tito', 'id' => 1));
  * </code>
  *
  * An options array can take the following parameters:
  *
  * <ul>
  * <li><b>select:</b> A SQL fragment for what fields to return such as: '*', 'people.*', 'first_name, last_name, id'</li>
  * <li><b>joins:</b> A SQL join fragment such as: 'JOIN roles ON(roles.user_id=user.id)' or a named association on the model</li>
  * <li><b>include:</b> TODO not implemented yet</li>
  * <li><b>conditions:</b> A SQL fragment such as: 'id=1', array('id=1'), array('name=? and id=?','Tito',1), array('name IN(?)', array('Tito','Bob')),
  * array('name' => 'Tito', 'id' => 1)</li>
  * <li><b>limit:</b> Number of records to limit the query to</li>
  * <li><b>offset:</b> The row offset to return results from for the query</li>
  * <li><b>order:</b> A SQL fragment for order such as: 'name asc', 'name asc, id desc'</li>
  * <li><b>readonly:</b> Return all the models in readonly mode</li>
  * <li><b>group:</b> A SQL group by fragment</li>
  * </ul>
  *
  * @throws {@link RecordNotFound} if no options are passed or finding by pk and no records matched
  * @return mixed An array of records found if doing a find_all otherwise a
  *   single Model object or null if it wasn't found. NULL is only return when
  *   doing a first/last find. If doing an all find and no records matched this
  *   will return an empty array.
  */
 public static function find()
 {
     $class = get_called_class();
     if (func_num_args() <= 0) {
         throw new RecordNotFound("Couldn't find {$class} without an ID");
     }
     $args = func_get_args();
     $options = static::extract_and_validate_options($args);
     $num_args = count($args);
     $single = true;
     if ($num_args > 0 && ($args[0] === 'all' || $args[0] === 'first' || $args[0] === 'last')) {
         switch ($args[0]) {
             case 'all':
                 $single = false;
                 break;
             case 'last':
                 if (!array_key_exists('order', $options)) {
                     $options['order'] = join(' DESC, ', static::table()->pk) . ' DESC';
                 } else {
                     $options['order'] = SQLBuilder::reverse_order($options['order']);
                 }
                 // fall thru
             // fall thru
             case 'first':
                 $options['limit'] = 1;
                 $options['offset'] = 0;
                 break;
         }
         $args = array_slice($args, 1);
         $num_args--;
     } elseif (1 === count($args) && 1 == $num_args) {
         $args = $args[0];
     }
     // anything left in $args is a find by pk
     if ($num_args > 0 && !isset($options['conditions'])) {
         return static::find_by_pk($args, $options);
     }
     $options['mapped_names'] = static::$alias_attribute;
     $list = static::table()->find($options);
     return $single ? !empty($list) ? $list[0] : null : $list;
 }
예제 #2
0
 public function test_reverse_order()
 {
     $this->assert_equals('id ASC, name DESC', SQLBuilder::reverse_order('id DESC, name ASC'));
     $this->assert_equals('id ASC, name DESC , zzz ASC', SQLBuilder::reverse_order('id DESC, name ASC , zzz DESC'));
     $this->assert_equals('id DESC, name DESC', SQLBuilder::reverse_order('id, name'));
     $this->assert_equals('id DESC', SQLBuilder::reverse_order('id'));
     $this->assert_equals('', SQLBuilder::reverse_order(''));
     $this->assert_equals(' ', SQLBuilder::reverse_order(' '));
     $this->assert_equals(null, SQLBuilder::reverse_order(null));
 }