/**
  * Find model records in the database
  *
  * Finding by primary key
  *
  * <code>
  * # Find record with id=123
  * ModelName::Find(123);
  *
  * # Find records with id in (1,2,3)
  * ModelName::Find(1, 2, 3);
  *
  * # Find records with options
  * ModelName::Find(1, 2, array('order' => 'name DESC'));
  * </code>
  *
  * Finding by conditions array
  * 
  * <code>
  * ModelName::Find(array('conditions' => array('name=?', 'John'), 'order' => ' id DESC');
  * ModelName::Find('first', array('conditions' => array('age > ?', 100));
  * ModelName::Find('all', array('conditions' => array('age in (?)', array(60, 70, 80)), 'order' => ' id DESC');
  * </code>
  * 
  * Finding by hash
  *
  * <code>
  * ModelName::Find(array('name' => 'John', 'gender' => 'm'));
  * ModelName::Find('first', array('name' => 'John', 'gender' => 'm'));
  * ModelName::Find('all', array('name' => 'John', 'gender' => 'm'));
  * ModelName::Find('last', array('name' => 'John', 'gender' => 'm'), array('order' => 'id DESC'));
  * </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>
  *
  * 
  */
 public static function Find()
 {
     // Get arguments
     $args = func_get_args();
     if (count($args) == 0) {
         $args = array('all');
     }
     $options = static::extractAndValidateOptions($args);
     $num_args = count($args);
     // Default find is a single record.
     $singleRecord = true;
     // Check if 'all', 'first' or 'last' was given
     if ($args[0] == Model::ALL || $args[0] == Model::LAST || $args[0] == Model::FIRST) {
         // Which was it?
         switch ($args[0]) {
             case Model::ALL:
                 // We'll return all records
                 $singleRecord = false;
                 break;
             case Model::LAST:
                 // Inverse the default order, and use 'first'
                 if (array_key_exists('order', $options)) {
                     // Reverse the order
                     $options['order'] = SQL::ReverseOrder($options['order']);
                 } else {
                     // Sort descending on table's primary key(s)
                     $options['order'] = implode(' DESC, ', static::getTable()->primaryKeys) . ' DESC';
                 }
                 // Continue with first...
             // Continue with first...
             case Model::FIRST:
                 $options['limit'] = 1;
                 $options['offset'] = 0;
                 break;
         }
         // Remove that argument
         array_shift($args);
         $num_args--;
         // Only one argument
     } elseif (count($args) == 1) {
         // Strip array around it
         $args = $args[0];
     }
     // Any arguments left?
     if ($num_args > 0 && !array_key_exists("conditions", $options)) {
         // Do a Find by Primary Key with the argument that's left
         return static::FindByPrimaryKey($args, $options);
     }
     // Find from table
     $list = static::getTable()->Find($options);
     // One record or recordlist?
     return $singleRecord ? !empty($list) ? $list[0] : null : $list;
 }
 public function Insert(&$attributes)
 {
     // Create query
     $sql = new SQL($this->connection, $this->getFullyQualifiedName());
     $sql->Insert($this->prepareData($attributes));
     // Execute
     $this->connection->Query($sql->Build(), $sql->getInsertValues());
 }