View source  
  <?php
class FakeRecord {
}
class DatabaseTestCase extends DrupalWebTestCase {
  function setUp() {
    parent::setUp('database_test');
    $schema['test'] = drupal_get_schema('test');
    $schema['test_people'] = drupal_get_schema('test_people');
    $schema['test_one_blob'] = drupal_get_schema('test_one_blob');
    $schema['test_two_blobs'] = drupal_get_schema('test_two_blobs');
    $schema['test_task'] = drupal_get_schema('test_task');
    $this
      ->installTables($schema);
    $this
      ->addSampleData();
  }
  
  function installTables($schema) {
    
    foreach ($schema as $name => $data) {
      if (db_table_exists($name)) {
        db_drop_table($name);
      }
      db_create_table($name, $data);
    }
    foreach ($schema as $name => $data) {
      $this
        ->assertTrue(db_table_exists($name), t('Table @name created successfully.', array(
        '@name' => $name,
      )));
    }
  }
  
  function ensureSampleDataNull() {
    $schema['test_null'] = drupal_get_schema('test_null');
    $this
      ->installTables($schema);
    db_insert('test_null')
      ->fields(array(
      'name',
      'age',
    ))
      ->values(array(
      'name' => 'Kermit',
      'age' => 25,
    ))
      ->values(array(
      'name' => 'Fozzie',
      'age' => NULL,
    ))
      ->values(array(
      'name' => 'Gonzo',
      'age' => 27,
    ))
      ->execute();
  }
  
  function addSampleData() {
    
    $john = db_insert('test')
      ->fields(array(
      'name' => 'John',
      'age' => 25,
      'job' => 'Singer',
    ))
      ->execute();
    $george = db_insert('test')
      ->fields(array(
      'name' => 'George',
      'age' => 27,
      'job' => 'Singer',
    ))
      ->execute();
    $ringo = db_insert('test')
      ->fields(array(
      'name' => 'Ringo',
      'age' => 28,
      'job' => 'Drummer',
    ))
      ->execute();
    $paul = db_insert('test')
      ->fields(array(
      'name' => 'Paul',
      'age' => 26,
      'job' => 'Songwriter',
    ))
      ->execute();
    db_insert('test_people')
      ->fields(array(
      'name' => 'Meredith',
      'age' => 30,
      'job' => 'Speaker',
    ))
      ->execute();
    db_insert('test_task')
      ->fields(array(
      'pid',
      'task',
      'priority',
    ))
      ->values(array(
      'pid' => $john,
      'task' => 'eat',
      'priority' => 3,
    ))
      ->values(array(
      'pid' => $john,
      'task' => 'sleep',
      'priority' => 4,
    ))
      ->values(array(
      'pid' => $john,
      'task' => 'code',
      'priority' => 1,
    ))
      ->values(array(
      'pid' => $george,
      'task' => 'sing',
      'priority' => 2,
    ))
      ->values(array(
      'pid' => $george,
      'task' => 'sleep',
      'priority' => 2,
    ))
      ->values(array(
      'pid' => $paul,
      'task' => 'found new band',
      'priority' => 1,
    ))
      ->values(array(
      'pid' => $paul,
      'task' => 'perform at superbowl',
      'priority' => 3,
    ))
      ->execute();
  }
}
class DatabaseConnectionTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Connection tests',
      'description' => 'Tests of the core database system.',
      'group' => 'Database',
    );
  }
  
  function testConnectionRouting() {
    
    $connection_info = Database::getConnectionInfo('default');
    Database::addConnectionInfo('default', 'slave', $connection_info['default']);
    $db1 = Database::getConnection('default', 'default');
    $db2 = Database::getConnection('slave', 'default');
    $this
      ->assertNotNull($db1, t('default connection is a real connection object.'));
    $this
      ->assertNotNull($db2, t('slave connection is a real connection object.'));
    $this
      ->assertNotIdentical($db1, $db2, t('Each target refers to a different connection.'));
    
    $db1b = Database::getConnection('default', 'default');
    $db2b = Database::getConnection('slave', 'default');
    $this
      ->assertIdentical($db1, $db1b, t('A second call to getConnection() returns the same object.'));
    $this
      ->assertIdentical($db2, $db2b, t('A second call to getConnection() returns the same object.'));
    
    $unknown_target = $this
      ->randomName();
    $db3 = Database::getConnection($unknown_target, 'default');
    $this
      ->assertNotNull($db3, t('Opening an unknown target returns a real connection object.'));
    $this
      ->assertIdentical($db1, $db3, t('An unknown target opens the default connection.'));
    
    $db3b = Database::getConnection($unknown_target, 'default');
    $this
      ->assertIdentical($db3, $db3b, t('A second call to getConnection() returns the same object.'));
  }
  
  function testConnectionRoutingOverride() {
    
    $connection_info = Database::getConnectionInfo('default');
    Database::addConnectionInfo('default', 'slave', $connection_info['default']);
    Database::ignoreTarget('default', 'slave');
    $db1 = Database::getConnection('default', 'default');
    $db2 = Database::getConnection('slave', 'default');
    $this
      ->assertIdentical($db1, $db2, t('Both targets refer to the same connection.'));
  }
  
  function testConnectionClosing() {
    
    $db1 = Database::getConnection('default', 'default');
    
    Database::closeConnection('default', 'default');
    $db2 = Database::getConnection('default', 'default');
    
    $this
      ->assertNotIdentical($db1, $db2, t('Opening the default connection after it is closed returns a new object.'));
  }
}
class DatabaseFetchTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Fetch tests',
      'description' => 'Test the Database system\'s various fetch capabilities.',
      'group' => 'Database',
    );
  }
  
  function testQueryFetchDefault() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ));
    $this
      ->assertTrue($result instanceof DatabaseStatementInterface, t('Result set is a Drupal statement object.'));
    foreach ($result as $record) {
      $records[] = $record;
      $this
        ->assertTrue(is_object($record), t('Record is an object.'));
      $this
        ->assertIdentical($record->name, 'John', t('25 year old is John.'));
    }
    $this
      ->assertIdentical(count($records), 1, t('There is only one record.'));
  }
  
  function testQueryFetchObject() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ), array(
      'fetch' => PDO::FETCH_OBJ,
    ));
    foreach ($result as $record) {
      $records[] = $record;
      $this
        ->assertTrue(is_object($record), t('Record is an object.'));
      $this
        ->assertIdentical($record->name, 'John', t('25 year old is John.'));
    }
    $this
      ->assertIdentical(count($records), 1, t('There is only one record.'));
  }
  
  function testQueryFetchArray() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ), array(
      'fetch' => PDO::FETCH_ASSOC,
    ));
    foreach ($result as $record) {
      $records[] = $record;
      if ($this
        ->assertTrue(is_array($record), t('Record is an array.'))) {
        $this
          ->assertIdentical($record['name'], 'John', t('Record can be accessed associatively.'));
      }
    }
    $this
      ->assertIdentical(count($records), 1, t('There is only one record.'));
  }
  
  function testQueryFetchClass() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ), array(
      'fetch' => 'FakeRecord',
    ));
    foreach ($result as $record) {
      $records[] = $record;
      if ($this
        ->assertTrue($record instanceof FakeRecord, t('Record is an object of class FakeRecord.'))) {
        $this
          ->assertIdentical($record->name, 'John', t('25 year old is John.'));
      }
    }
    $this
      ->assertIdentical(count($records), 1, t('There is only one record.'));
  }
}
class DatabaseFetch2TestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Fetch tests, part 2',
      'description' => 'Test the Database system\'s various fetch capabilities.',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp();
  }
  
  function testQueryFetchNum() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ), array(
      'fetch' => PDO::FETCH_NUM,
    ));
    foreach ($result as $record) {
      $records[] = $record;
      if ($this
        ->assertTrue(is_array($record), t('Record is an array.'))) {
        $this
          ->assertIdentical($record[0], 'John', t('Record can be accessed numerically.'));
      }
    }
    $this
      ->assertIdentical(count($records), 1, 'There is only one record');
  }
  
  function testQueryFetchBoth() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age = :age', array(
      ':age' => 25,
    ), array(
      'fetch' => PDO::FETCH_BOTH,
    ));
    foreach ($result as $record) {
      $records[] = $record;
      if ($this
        ->assertTrue(is_array($record), t('Record is an array.'))) {
        $this
          ->assertIdentical($record[0], 'John', t('Record can be accessed numerically.'));
        $this
          ->assertIdentical($record['name'], 'John', t('Record can be accessed associatively.'));
      }
    }
    $this
      ->assertIdentical(count($records), 1, t('There is only one record.'));
  }
  
  function testQueryFetchCol() {
    $records = array();
    $result = db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ));
    $column = $result
      ->fetchCol();
    $this
      ->assertIdentical(count($column), 3, t('fetchCol() returns the right number of records.'));
    $result = db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ));
    $i = 0;
    foreach ($result as $record) {
      $this
        ->assertIdentical($record->name, $column[$i++], t('Column matches direct accesss.'));
    }
  }
}
class DatabaseInsertTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Insert tests',
      'description' => 'Test the Insert query builder.',
      'group' => 'Database',
    );
  }
  
  function testSimpleInsert() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $query = db_insert('test');
    $query
      ->fields(array(
      'name' => 'Yoko',
      'age' => '29',
    ));
    $query
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $this
      ->assertIdentical($num_records_before + 1, (int) $num_records_after, t('Record inserts correctly.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Yoko',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '29', t('Can retrieve after inserting.'));
  }
  
  function testMultiInsert() {
    $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $query = db_insert('test');
    $query
      ->fields(array(
      'name' => 'Larry',
      'age' => '30',
    ));
    
    $query
      ->values(array(
      'age' => '31',
      'name' => 'Curly',
    ));
    
    $query
      ->values(array(
      'Moe',
      '32',
    ));
    $query
      ->execute();
    $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $this
      ->assertIdentical($num_records_before + 3, $num_records_after, t('Record inserts correctly.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Larry',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '30', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Curly',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '31', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Moe',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '32', t('Can retrieve after inserting.'));
  }
  
  function testRepeatedInsert() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $query = db_insert('test');
    $query
      ->fields(array(
      'name' => 'Larry',
      'age' => '30',
    ));
    $query
      ->execute();
    
    $query
      ->values(array(
      'age' => '31',
      'name' => 'Curly',
    ));
    $query
      ->execute();
    
    $query
      ->values(array(
      'Moe',
      '32',
    ));
    $query
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $this
      ->assertIdentical((int) $num_records_before + 3, (int) $num_records_after, t('Record inserts correctly.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Larry',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '30', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Curly',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '31', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Moe',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '32', t('Can retrieve after inserting.'));
  }
  
  function testInsertFieldOnlyDefinintion() {
    
    db_insert('test')
      ->fields(array(
      'name',
      'age',
    ))
      ->values(array(
      'Larry',
      '30',
    ))
      ->values(array(
      'Curly',
      '31',
    ))
      ->values(array(
      'Moe',
      '32',
    ))
      ->execute();
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Larry',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '30', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Curly',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '31', t('Can retrieve after inserting.'));
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Moe',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '32', t('Can retrieve after inserting.'));
  }
  
  function testInsertLastInsertID() {
    $id = db_insert('test')
      ->fields(array(
      'name' => 'Larry',
      'age' => '30',
    ))
      ->execute();
    $this
      ->assertIdentical($id, '5', t('Auto-increment ID returned successfully.'));
  }
  
  function testInsertSelect() {
    $query = db_select('test_people', 'tp');
    
    $query
      ->addExpression('tp.age', 'age');
    $query
      ->fields('tp', array(
      'name',
      'job',
    ))
      ->condition('tp.name', 'Meredith');
    
    db_insert('test')
      ->from($query)
      ->execute();
    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Meredith',
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_age, '30', t('Can retrieve after inserting.'));
  }
}
class DatabaseInsertLOBTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Insert tests, LOB fields',
      'description' => 'Test the Insert query builder with LOB fields.',
      'group' => 'Database',
    );
  }
  
  function testInsertOneBlob() {
    $data = "This is\0a test.";
    $this
      ->assertTrue(strlen($data) === 15, t('Test data contains a NULL.'));
    $id = db_insert('test_one_blob')
      ->fields(array(
      'blob1' => $data,
    ))
      ->execute();
    $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchAssoc();
    $this
      ->assertTrue($r['blob1'] === $data, t('Can insert a blob: id @id, @data.', array(
      '@id' => $id,
      '@data' => serialize($r),
    )));
  }
  
  function testInsertMultipleBlob() {
    $id = db_insert('test_two_blobs')
      ->fields(array(
      'blob1' => 'This is',
      'blob2' => 'a test',
    ))
      ->execute();
    $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchAssoc();
    $this
      ->assertTrue($r['blob1'] === 'This is' && $r['blob2'] === 'a test', t('Can insert multiple blobs per row.'));
  }
}
class DatabaseInsertDefaultsTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Insert tests, default fields',
      'description' => 'Test the Insert query builder with default values.',
      'group' => 'Database',
    );
  }
  
  function testDefaultInsert() {
    $query = db_insert('test')
      ->useDefaults(array(
      'job',
    ));
    $id = $query
      ->execute();
    $schema = drupal_get_schema('test');
    $job = db_query('SELECT job FROM {test} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchField();
    $this
      ->assertEqual($job, $schema['fields']['job']['default'], t('Default field value is set.'));
  }
  
  function testDefaultEmptyInsert() {
    $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    try {
      $result = db_insert('test')
        ->execute();
      
      $this
        ->fail(t('Expected exception NoFieldsException has not been thrown.'));
    } catch (NoFieldsException $e) {
      $this
        ->pass(t('Expected exception NoFieldsException has been thrown.'));
    }
    $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $this
      ->assertIdentical($num_records_before, $num_records_after, t('Do nothing as no fields are specified.'));
  }
  
  function testDefaultInsertWithFields() {
    $query = db_insert('test')
      ->fields(array(
      'name' => 'Bob',
    ))
      ->useDefaults(array(
      'job',
    ));
    $id = $query
      ->execute();
    $schema = drupal_get_schema('test');
    $job = db_query('SELECT job FROM {test} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchField();
    $this
      ->assertEqual($job, $schema['fields']['job']['default'], t('Default field value is set.'));
  }
}
class DatabaseUpdateTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update tests',
      'description' => 'Test the Update query builder.',
      'group' => 'Database',
    );
  }
  
  function testSimpleUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'name' => 'Tiffany',
    ))
      ->condition('id', 1)
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $saved_name = db_query('SELECT name FROM {test} WHERE id = :id', array(
      ':id' => 1,
    ))
      ->fetchField();
    $this
      ->assertIdentical($saved_name, 'Tiffany', t('Updated name successfully.'));
  }
  
  function testMultiUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('job', 'Singer')
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testMultiGTUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('age', 26, '>')
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testWhereUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->where('age > :age', array(
      ':age' => 26,
    ))
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testWhereAndConditionUpdate() {
    $update = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->where('age > :age', array(
      ':age' => 26,
    ))
      ->condition('name', 'Ringo');
    $num_updated = $update
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '1', t('Updated fields successfully.'));
  }
}
class DatabaseUpdateComplexTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update tests, Complex',
      'description' => 'Test the Update query builder, complex queries.',
      'group' => 'Database',
    );
  }
  
  function testOrConditionUpdate() {
    $update = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition(db_or()
      ->condition('name', 'John')
      ->condition('name', 'Paul'));
    $num_updated = $update
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testInConditionUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('name', array(
      'John',
      'Paul',
    ), 'IN')
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testNotInConditionUpdate() {
    
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('name', array(
      'John',
      'Paul',
      'George',
    ), 'NoT IN')
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '1', t('Updated fields successfully.'));
  }
  
  function testBetweenConditionUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('age', array(
      25,
      26,
    ), 'BETWEEN')
      ->execute();
    $this
      ->assertIdentical($num_updated, 2, t('Updated 2 records.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '2', t('Updated fields successfully.'));
  }
  
  function testLikeConditionUpdate() {
    $num_updated = db_update('test')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->condition('name', '%ge%', 'LIKE')
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '1', t('Updated fields successfully.'));
  }
  
  function testUpdateExpression() {
    $before_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetchField();
    $GLOBALS['larry_test'] = 1;
    $num_updated = db_update('test')
      ->condition('name', 'Ringo')
      ->fields(array(
      'job' => 'Musician',
    ))
      ->expression('age', 'age + :age', array(
      ':age' => 4,
    ))
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(
      ':job' => 'Musician',
    ))
      ->fetchField();
    $this
      ->assertIdentical($num_matches, '1', t('Updated fields successfully.'));
    $person = db_query('SELECT * FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Ringo', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, $before_age + 4, t('Age set correctly.'));
    $this
      ->assertEqual($person->job, 'Musician', t('Job set correctly.'));
    $GLOBALS['larry_test'] = 0;
  }
  
  function testUpdateOnlyExpression() {
    $before_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetchField();
    $num_updated = db_update('test')
      ->condition('name', 'Ringo')
      ->expression('age', 'age + :age', array(
      ':age' => 4,
    ))
      ->execute();
    $this
      ->assertIdentical($num_updated, 1, t('Updated 1 record.'));
    $after_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetchField();
    $this
      ->assertEqual($before_age + 4, $after_age, t('Age updated correctly'));
  }
}
class DatabaseUpdateLOBTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Update tests, LOB',
      'description' => 'Test the Update query builder with LOB fields.',
      'group' => 'Database',
    );
  }
  
  function testUpdateOneBlob() {
    $data = "This is\0a test.";
    $this
      ->assertTrue(strlen($data) === 15, t('Test data contains a NULL.'));
    $id = db_insert('test_one_blob')
      ->fields(array(
      'blob1' => $data,
    ))
      ->execute();
    $data .= $data;
    db_update('test_one_blob')
      ->condition('id', $id)
      ->fields(array(
      'blob1' => $data,
    ))
      ->execute();
    $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchAssoc();
    $this
      ->assertTrue($r['blob1'] === $data, t('Can update a blob: id @id, @data.', array(
      '@id' => $id,
      '@data' => serialize($r),
    )));
  }
  
  function testUpdateMultipleBlob() {
    $id = db_insert('test_two_blobs')
      ->fields(array(
      'blob1' => 'This is',
      'blob2' => 'a test',
    ))
      ->execute();
    db_update('test_two_blobs')
      ->condition('id', $id)
      ->fields(array(
      'blob1' => 'and so',
      'blob2' => 'is this',
    ))
      ->execute();
    $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(
      ':id' => $id,
    ))
      ->fetchAssoc();
    $this
      ->assertTrue($r['blob1'] === 'and so' && $r['blob2'] === 'is this', t('Can update multiple blobs per row.'));
  }
}
class DatabaseDeleteTruncateTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Delete/Truncate tests',
      'description' => 'Test the Delete and Truncate query builders.',
      'group' => 'Database',
    );
  }
  
  function testSimpleDelete() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $num_deleted = db_delete('test')
      ->condition('id', 1)
      ->execute();
    $this
      ->assertIdentical($num_deleted, 1, t('Deleted 1 record.'));
    $num_records_after = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after + $num_deleted, t('Deletion adds up.'));
  }
  
  function testTruncate() {
    $num_records_before = db_query("SELECT COUNT(*) FROM {test}")
      ->fetchField();
    db_truncate('test')
      ->execute();
    $num_records_after = db_query("SELECT COUNT(*) FROM {test}")
      ->fetchField();
    $this
      ->assertEqual(0, $num_records_after, t('Truncate really deletes everything.'));
  }
}
class DatabaseMergeTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Merge tests',
      'description' => 'Test the Merge query builder.',
      'group' => 'Database',
    );
  }
  
  function testMergeInsert() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $result = db_merge('test_people')
      ->key(array(
      'job' => 'Presenter',
    ))
      ->fields(array(
      'age' => 31,
      'name' => 'Tiffany',
    ))
      ->execute();
    $this
      ->assertEqual($result, MergeQuery::STATUS_INSERT, t('Insert status returned.'));
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before + 1, $num_records_after, t('Merge inserted properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Presenter',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Tiffany', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, 31, t('Age set correctly.'));
    $this
      ->assertEqual($person->job, 'Presenter', t('Job set correctly.'));
  }
  
  function testMergeUpdate() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $result = db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->fields(array(
      'age' => 31,
      'name' => 'Tiffany',
    ))
      ->execute();
    $this
      ->assertEqual($result, MergeQuery::STATUS_UPDATE, t('Update status returned.'));
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge updated properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Tiffany', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, 31, t('Age set correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job set correctly.'));
  }
  
  function testMergeUpdateExcept() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->fields(array(
      'age' => 31,
      'name' => 'Tiffany',
    ))
      ->updateExcept('age')
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge updated properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Tiffany', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, 30, t('Age skipped correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job set correctly.'));
  }
  
  function testMergeUpdateExplicit() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->fields(array(
      'age' => 31,
      'name' => 'Tiffany',
    ))
      ->update(array(
      'name' => 'Joe',
    ))
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge updated properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Joe', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, 30, t('Age skipped correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job set correctly.'));
  }
  
  function testMergeUpdateExpression() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $age_before = db_query('SELECT age FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetchField();
    
    db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->fields(array(
      'age' => 31,
      'name' => 'Tiffany',
    ))
      ->expression('age', 'age + :age', array(
      ':age' => 4,
    ))
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge updated properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Tiffany', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, $age_before + 4, t('Age updated correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job set correctly.'));
  }
  
  function testMergeInsertWithoutUpdate() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    db_merge('test_people')
      ->key(array(
      'job' => 'Presenter',
    ))
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before + 1, $num_records_after, t('Merge inserted properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Presenter',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, '', t('Name set correctly.'));
    $this
      ->assertEqual($person->age, 0, t('Age set correctly.'));
    $this
      ->assertEqual($person->job, 'Presenter', t('Job set correctly.'));
  }
  
  function testMergeUpdateWithoutUpdate() {
    $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge skipped properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Meredith', t('Name skipped correctly.'));
    $this
      ->assertEqual($person->age, 30, t('Age skipped correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job skipped correctly.'));
    db_merge('test_people')
      ->key(array(
      'job' => 'Speaker',
    ))
      ->fields(array(
      'age' => 31,
    ))
      ->updateExcept(array(
      'age',
    ))
      ->execute();
    $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')
      ->fetchField();
    $this
      ->assertEqual($num_records_before, $num_records_after, t('Merge skipped properly.'));
    $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(
      ':job' => 'Speaker',
    ))
      ->fetch();
    $this
      ->assertEqual($person->name, 'Meredith', t('Name skipped correctly.'));
    $this
      ->assertEqual($person->age, 30, t('Age skipped correctly.'));
    $this
      ->assertEqual($person->job, 'Speaker', t('Job skipped correctly.'));
  }
  
  function testInvalidMerge() {
    try {
      
      db_merge('test_people')
        ->fields(array(
        'age' => 31,
        'name' => 'Tiffany',
      ))
        ->execute();
    } catch (InvalidMergeQueryException $e) {
      $this
        ->pass(t('InvalidMergeQueryException thrown for invalid query.'));
      return;
    }
    $this
      ->fail(t('No InvalidMergeQueryException thrown'));
  }
}
class DatabaseSelectTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Select tests',
      'description' => 'Test the Select query builder.',
      'group' => 'Database',
    );
  }
  
  function testSimpleSelect() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $result = $query
      ->execute();
    $num_records = 0;
    foreach ($result as $record) {
      $num_records++;
    }
    $this
      ->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
  }
  
  function testSimpleSelectConditional() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->condition('age', 27);
    $result = $query
      ->execute();
    
    $this
      ->assertEqual($name_field, 'name', t('Name field alias is correct.'));
    $this
      ->assertEqual($age_field, 'age', t('Age field alias is correct.'));
    
    $record = $result
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Fetched name is correct.'));
    $this
      ->assertEqual($record->{$age_field}, 27, t('Fetched age is correct.'));
  }
  
  function testSimpleSelectExpression() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addExpression("age*2", 'double_age');
    $query
      ->condition('age', 27);
    $result = $query
      ->execute();
    
    $this
      ->assertEqual($name_field, 'name', t('Name field alias is correct.'));
    $this
      ->assertEqual($age_field, 'double_age', t('Age field alias is correct.'));
    
    $record = $result
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Fetched name is correct.'));
    $this
      ->assertEqual($record->{$age_field}, 27 * 2, t('Fetched age expression is correct.'));
  }
  
  function testSimpleSelectExpressionMultiple() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_double_field = $query
      ->addExpression("age*2");
    $age_triple_field = $query
      ->addExpression("age*3");
    $query
      ->condition('age', 27);
    $result = $query
      ->execute();
    
    $this
      ->assertEqual($age_double_field, 'expression', t('Double age field alias is correct.'));
    $this
      ->assertEqual($age_triple_field, 'expression_2', t('Triple age field alias is correct.'));
    
    $record = $result
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Fetched name is correct.'));
    $this
      ->assertEqual($record->{$age_double_field}, 27 * 2, t('Fetched double age expression is correct.'));
    $this
      ->assertEqual($record->{$age_triple_field}, 27 * 3, t('Fetched triple age expression is correct.'));
  }
  
  function testSimpleSelectMultipleFields() {
    $record = db_select('test')
      ->fields('test', array(
      'id',
      'name',
      'age',
      'job',
    ))
      ->condition('age', 27)
      ->execute()
      ->fetchObject();
    
    $this
      ->assertNotNull($record->id, t('ID field is present.'));
    $this
      ->assertNotNull($record->name, t('Name field is present.'));
    $this
      ->assertNotNull($record->age, t('Age field is present.'));
    $this
      ->assertNotNull($record->job, t('Job field is present.'));
    
    $this
      ->assertEqual($record->id, 2, t('ID field has the correct value.'));
    $this
      ->assertEqual($record->name, 'George', t('Name field has the correct value.'));
    $this
      ->assertEqual($record->age, 27, t('Age field has the correct value.'));
    $this
      ->assertEqual($record->job, 'Singer', t('Job field has the correct value.'));
  }
  
  function testSimpleSelectAllFields() {
    $record = db_select('test')
      ->fields('test')
      ->condition('age', 27)
      ->execute()
      ->fetchObject();
    
    $this
      ->assertNotNull($record->id, t('ID field is present.'));
    $this
      ->assertNotNull($record->name, t('Name field is present.'));
    $this
      ->assertNotNull($record->age, t('Age field is present.'));
    $this
      ->assertNotNull($record->job, t('Job field is present.'));
    
    $this
      ->assertEqual($record->id, 2, t('ID field has the correct value.'));
    $this
      ->assertEqual($record->name, 'George', t('Name field has the correct value.'));
    $this
      ->assertEqual($record->age, 27, t('Age field has the correct value.'));
    $this
      ->assertEqual($record->job, 'Singer', t('Job field has the correct value.'));
  }
  
  function testNullCondition() {
    $this
      ->ensureSampleDataNull();
    $names = db_select('test_null', 'tn')
      ->fields('tn', array(
      'name',
    ))
      ->isNull('age')
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual(count($names), 1, t('Correct number of records found with NULL age.'));
    $this
      ->assertEqual($names[0], 'Fozzie', t('Correct record returned for NULL age.'));
  }
  
  function testNotNullCondition() {
    $this
      ->ensureSampleDataNull();
    $names = db_select('test_null', 'tn')
      ->fields('tn', array(
      'name',
    ))
      ->isNotNull('tn.age')
      ->orderBy('name')
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual(count($names), 2, t('Correct number of records found withNOT NULL age.'));
    $this
      ->assertEqual($names[0], 'Gonzo', t('Correct record returned for NOT NULL age.'));
    $this
      ->assertEqual($names[1], 'Kermit', t('Correct record returned for NOT NULL age.'));
  }
  
  function testUnion() {
    $query_1 = db_select('test', 't')
      ->fields('t', array(
      'name',
    ))
      ->condition('age', array(
      27,
      28,
    ), 'IN');
    $query_2 = db_select('test', 't')
      ->fields('t', array(
      'name',
    ))
      ->condition('age', 28);
    $query_1
      ->union($query_2);
    $names = $query_1
      ->execute()
      ->fetchCol();
    
    $this
      ->assertEqual(count($names), 2, t('UNION correctly discarded duplicates.'));
    $this
      ->assertEqual($names[0], 'George', t('First query returned correct name.'));
    $this
      ->assertEqual($names[1], 'Ringo', t('Second query returned correct name.'));
  }
  
  function testUnionAll() {
    $query_1 = db_select('test', 't')
      ->fields('t', array(
      'name',
    ))
      ->condition('age', array(
      27,
      28,
    ), 'IN');
    $query_2 = db_select('test', 't')
      ->fields('t', array(
      'name',
    ))
      ->condition('age', 28);
    $query_1
      ->union($query_2, 'ALL');
    $names = $query_1
      ->execute()
      ->fetchCol();
    
    $this
      ->assertEqual(count($names), 3, t('UNION ALL correctly preserved duplicates.'));
    $this
      ->assertEqual($names[0], 'George', t('First query returned correct first name.'));
    $this
      ->assertEqual($names[1], 'Ringo', t('Second query returned correct second name.'));
    $this
      ->assertEqual($names[2], 'Ringo', t('Third query returned correct name.'));
  }
  
  function testRandomOrder() {
    
    $number_of_items = 52;
    while (db_query("SELECT MAX(id) FROM {test}")
      ->fetchField() < $number_of_items) {
      db_insert('test')
        ->fields(array(
        'name' => $this
          ->randomName(),
      ))
        ->execute();
    }
    
    $expected_ids = range(1, $number_of_items);
    $ordered_ids = db_select('test', 't')
      ->fields('t', array(
      'id',
    ))
      ->range(0, $number_of_items)
      ->orderBy('id')
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual($ordered_ids, $expected_ids, t('A query without random ordering returns IDs in the correct order.'));
    
    $randomized_ids = db_select('test', 't')
      ->fields('t', array(
      'id',
    ))
      ->range(0, $number_of_items)
      ->orderRandom()
      ->execute()
      ->fetchCol();
    $this
      ->assertNotEqual($randomized_ids, $ordered_ids, t('A query with random ordering returns an unordered set of IDs.'));
    $sorted_ids = $randomized_ids;
    sort($sorted_ids);
    $this
      ->assertEqual($sorted_ids, $ordered_ids, t('After sorting the random list, the result matches the original query.'));
    
    $randomized_ids_second_set = db_select('test', 't')
      ->fields('t', array(
      'id',
    ))
      ->range(0, $number_of_items)
      ->orderRandom()
      ->execute()
      ->fetchCol();
    $this
      ->assertNotEqual($randomized_ids_second_set, $randomized_ids, t('Performing the query with random ordering a second time returns IDs in a different order.'));
    $sorted_ids_second_set = $randomized_ids_second_set;
    sort($sorted_ids_second_set);
    $this
      ->assertEqual($sorted_ids_second_set, $sorted_ids, t('After sorting the second random list, the result matches the sorted version of the first random list.'));
  }
}
class DatabaseSelectSubqueryTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Select tests, subqueries',
      'description' => 'Test the Select query builder.',
      'group' => 'Database',
    );
  }
  
  function testFromSubquerySelect() {
    
    $subquery = db_select('test_task', 'tt');
    $subquery
      ->addField('tt', 'pid', 'pid');
    $subquery
      ->addField('tt', 'task', 'task');
    $subquery
      ->condition('priority', 1);
    
    $select = db_select($subquery, 'tt2');
    $select
      ->join('test', 't', 't.id=tt2.pid');
    $select
      ->addField('t', 'name');
    $select
      ->condition('task', 'code');
    
    $people = $select
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual(count($people), 1, t('Returned the correct number of rows.'));
  }
  
  function testConditionSubquerySelect() {
    
    $subquery = db_select('test_task', 'tt');
    $subquery
      ->addField('tt', 'pid', 'pid');
    $subquery
      ->condition('tt.priority', 1);
    
    $select = db_select('test_task', 'tt2');
    $select
      ->addField('tt2', 'task');
    $select
      ->condition('tt2.pid', $subquery, 'IN');
    
    $people = $select
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual(count($people), 5, t('Returned the correct number of rows.'));
  }
  
  function testJoinSubquerySelect() {
    
    $subquery = db_select('test_task', 'tt');
    $subquery
      ->addField('tt', 'pid', 'pid');
    $subquery
      ->condition('priority', 1);
    
    $select = db_select('test', 't');
    $select
      ->join($subquery, 'tt', 't.id=tt.pid');
    $select
      ->addField('t', 'name');
    
    $people = $select
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual(count($people), 2, t('Returned the correct number of rows.'));
  }
}
class DatabaseSelectOrderedTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Select tests, ordered',
      'description' => 'Test the Select query builder.',
      'group' => 'Database',
    );
  }
  
  function testSimpleSelectOrdered() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->orderBy($age_field);
    $result = $query
      ->execute();
    $num_records = 0;
    $last_age = 0;
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue($record->age >= $last_age, t('Results returned in correct order.'));
      $last_age = $record->age;
    }
    $this
      ->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
  }
  
  function testSimpleSelectMultiOrdered() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $job_field = $query
      ->addField('test', 'job');
    $query
      ->orderBy($job_field);
    $query
      ->orderBy($age_field);
    $result = $query
      ->execute();
    $num_records = 0;
    $expected = array(
      array(
        'Ringo',
        28,
        'Drummer',
      ),
      array(
        'John',
        25,
        'Singer',
      ),
      array(
        'George',
        27,
        'Singer',
      ),
      array(
        'Paul',
        26,
        'Songwriter',
      ),
    );
    $results = $result
      ->fetchAll(PDO::FETCH_NUM);
    foreach ($expected as $k => $record) {
      $num_records++;
      foreach ($record as $kk => $col) {
        if ($expected[$k][$kk] != $results[$k][$kk]) {
          $this
            ->assertTrue(FALSE, t('Results returned in correct order.'));
        }
      }
    }
    $this
      ->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
  }
  
  function testSimpleSelectOrderedDesc() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->orderBy($age_field, 'DESC');
    $result = $query
      ->execute();
    $num_records = 0;
    $last_age = 100000000;
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue($record->age <= $last_age, t('Results returned in correct order.'));
      $last_age = $record->age;
    }
    $this
      ->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
  }
}
class DatabaseSelectComplexTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Select tests, complex',
      'description' => 'Test the Select query builder with more complex queries.',
      'group' => 'Database',
    );
  }
  
  function testDefaultJoin() {
    $query = db_select('test_task', 't');
    $people_alias = $query
      ->join('test', 'p', 't.pid = p.id');
    $name_field = $query
      ->addField($people_alias, 'name', 'name');
    $task_field = $query
      ->addField('t', 'task', 'task');
    $priority_field = $query
      ->addField('t', 'priority', 'priority');
    $query
      ->orderBy($priority_field);
    $result = $query
      ->execute();
    $num_records = 0;
    $last_priority = 0;
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue($record->{$priority_field} >= $last_priority, t('Results returned in correct order.'));
      $this
        ->assertNotEqual($record->{$name_field}, 'Ringo', t('Taskless person not selected.'));
      $last_priority = $record->{$priority_field};
    }
    $this
      ->assertEqual($num_records, 7, t('Returned the correct number of rows.'));
  }
  
  function testLeftOuterJoin() {
    $query = db_select('test', 'p');
    $people_alias = $query
      ->leftJoin('test_task', 't', 't.pid = p.id');
    $name_field = $query
      ->addField('p', 'name', 'name');
    $task_field = $query
      ->addField($people_alias, 'task', 'task');
    $priority_field = $query
      ->addField($people_alias, 'priority', 'priority');
    $query
      ->orderBy($name_field);
    $result = $query
      ->execute();
    $num_records = 0;
    $last_name = 0;
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue(strcmp($record->{$name_field}, $last_name) >= 0, t('Results returned in correct order.'));
      $last_priority = $record->{$name_field};
    }
    $this
      ->assertEqual($num_records, 8, t('Returned the correct number of rows.'));
  }
  
  function testGroupBy() {
    $query = db_select('test_task', 't');
    $count_field = $query
      ->addExpression('COUNT(task)', 'num');
    $task_field = $query
      ->addField('t', 'task');
    $query
      ->orderBy($count_field);
    $query
      ->groupBy($task_field);
    $result = $query
      ->execute();
    $num_records = 0;
    $last_count = 0;
    $records = array();
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue($record->{$count_field} >= $last_count, t('Results returned in correct order.'));
      $last_count = $record->{$count_field};
      $records[$record->{$task_field}] = $record->{$count_field};
    }
    $correct_results = array(
      'eat' => 1,
      'sleep' => 2,
      'code' => 1,
      'found new band' => 1,
      'perform at superbowl' => 1,
    );
    foreach ($correct_results as $task => $count) {
      $this
        ->assertEqual($records[$task], $count, t("Correct number of '@task' records found.", array(
        '@task' => $task,
      )));
    }
    $this
      ->assertEqual($num_records, 6, t('Returned the correct number of total rows.'));
  }
  
  function testGroupByAndHaving() {
    $query = db_select('test_task', 't');
    $count_field = $query
      ->addExpression('COUNT(task)', 'num');
    $task_field = $query
      ->addField('t', 'task');
    $query
      ->orderBy($count_field);
    $query
      ->groupBy($task_field);
    $query
      ->havingCondition('COUNT(task)', 2, '>=');
    $result = $query
      ->execute();
    $num_records = 0;
    $last_count = 0;
    $records = array();
    foreach ($result as $record) {
      $num_records++;
      $this
        ->assertTrue($record->{$count_field} >= 2, t('Record has the minimum count.'));
      $this
        ->assertTrue($record->{$count_field} >= $last_count, t('Results returned in correct order.'));
      $last_count = $record->{$count_field};
      $records[$record->{$task_field}] = $record->{$count_field};
    }
    $correct_results = array(
      'sleep' => 2,
    );
    foreach ($correct_results as $task => $count) {
      $this
        ->assertEqual($records[$task], $count, t("Correct number of '@task' records found.", array(
        '@task' => $task,
      )));
    }
    $this
      ->assertEqual($num_records, 1, t('Returned the correct number of total rows.'));
  }
  
  function testRange() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->range(0, 2);
    $result = $query
      ->execute();
    $num_records = 0;
    foreach ($result as $record) {
      $num_records++;
    }
    $this
      ->assertEqual($num_records, 2, t('Returned the correct number of rows.'));
  }
  
  function testDistinct() {
    $query = db_select('test_task');
    $task_field = $query
      ->addField('test_task', 'task');
    $query
      ->distinct();
    $result = $query
      ->execute();
    $num_records = 0;
    foreach ($result as $record) {
      $num_records++;
    }
    $this
      ->assertEqual($num_records, 6, t('Returned the correct number of rows.'));
  }
  
  function testCountQuery() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->orderBy('name');
    $count = $query
      ->countQuery()
      ->execute()
      ->fetchField();
    $this
      ->assertEqual($count, 4, t('Counted the correct number of records.'));
    
    $record = $query
      ->execute()
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Correct data retrieved.'));
    $this
      ->assertEqual($record->{$age_field}, 27, t('Correct data retrieved.'));
  }
  
  function testNestedConditions() {
    
    $query = db_select('test');
    $query
      ->addField('test', 'job');
    $query
      ->condition('name', 'Paul');
    $query
      ->condition(db_or()
      ->condition('age', 26)
      ->condition('age', 27));
    $job = $query
      ->execute()
      ->fetchField();
    $this
      ->assertEqual($job, 'Songwriter', t('Correct data retrieved.'));
  }
}
class DatabaseSelectPagerDefaultTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Pager query tests',
      'description' => 'Test the pager query extender.',
      'group' => 'Database',
    );
  }
  
  function testEvenPagerQuery() {
    
    $limit = 2;
    $count = db_query('SELECT COUNT(*) FROM {test}')
      ->fetchField();
    $correct_number = $limit;
    $num_pages = floor($count / $limit);
    
    if (!($num_pages * $limit < $count)) {
      $num_pages--;
    }
    for ($page = 0; $page <= $num_pages; ++$page) {
      $this
        ->drupalGet('database_test/pager_query_even/' . $limit, array(
        'query' => array(
          'page' => $page,
        ),
      ));
      $data = json_decode($this
        ->drupalGetContent());
      if ($page == $num_pages) {
        $correct_number = $count - $limit * $page;
      }
      $this
        ->assertEqual(count($data->names), $correct_number, t('Correct number of records returned by pager: @number', array(
        '@number' => $correct_number,
      )));
    }
  }
  
  function testOddPagerQuery() {
    
    $limit = 2;
    $count = db_query('SELECT COUNT(*) FROM {test_task}')
      ->fetchField();
    $correct_number = $limit;
    $num_pages = floor($count / $limit);
    
    if (!($num_pages * $limit < $count)) {
      $num_pages--;
    }
    for ($page = 0; $page <= $num_pages; ++$page) {
      $this
        ->drupalGet('database_test/pager_query_odd/' . $limit, array(
        'query' => array(
          'page' => $page,
        ),
      ));
      $data = json_decode($this
        ->drupalGetContent());
      if ($page == $num_pages) {
        $correct_number = $count - $limit * $page;
      }
      $this
        ->assertEqual(count($data->names), $correct_number, t('Correct number of records returned by pager: @number', array(
        '@number' => $correct_number,
      )));
    }
  }
  
  function testInnerPagerQuery() {
    $query = db_select('test', 't')
      ->extend('PagerDefault');
    $query
      ->fields('t', array(
      'age',
    ))
      ->orderBy('age')
      ->limit(5);
    $outer_query = db_select($query);
    $outer_query
      ->addField('subquery', 'age');
    $ages = $outer_query
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual($ages, array(
      25,
      26,
      27,
      28,
    ), t('Inner pager query returned the correct ages.'));
  }
  
  function testHavingPagerQuery() {
    $query = db_select('test', 't')
      ->extend('PagerDefault');
    $query
      ->fields('t', array(
      'name',
    ))
      ->orderBy('name')
      ->groupBy('name')
      ->having('MAX(age) > :count', array(
      ':count' => 26,
    ))
      ->limit(5);
    $ages = $query
      ->execute()
      ->fetchCol();
    $this
      ->assertEqual($ages, array(
      'George',
      'Ringo',
    ), t('Pager query with having expression returned the correct ages.'));
  }
}
class DatabaseSelectTableSortDefaultTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Tablesort query tests',
      'description' => 'Test the tablesort query extender.',
      'group' => 'Database',
    );
  }
  
  function testTableSortQuery() {
    $sorts = array(
      array(
        'field' => t('Task ID'),
        'sort' => 'desc',
        'first' => 'perform at superbowl',
        'last' => 'eat',
      ),
      array(
        'field' => t('Task ID'),
        'sort' => 'asc',
        'first' => 'eat',
        'last' => 'perform at superbowl',
      ),
      array(
        'field' => t('Task'),
        'sort' => 'asc',
        'first' => 'code',
        'last' => 'sleep',
      ),
      array(
        'field' => t('Task'),
        'sort' => 'desc',
        'first' => 'sleep',
        'last' => 'code',
      ),
    );
    foreach ($sorts as $sort) {
      $this
        ->drupalGet('database_test/tablesort/', array(
        'query' => array(
          'order' => $sort['field'],
          'sort' => $sort['sort'],
        ),
      ));
      $data = json_decode($this
        ->drupalGetContent());
      $first = array_shift($data->tasks);
      $last = array_pop($data->tasks);
      $this
        ->assertEqual($first->task, $sort['first'], t('Items appear in the correct order.'));
      $this
        ->assertEqual($last->task, $sort['last'], t('Items appear in the correct order.'));
    }
  }
  
  function testTableSortQueryFirst() {
    $sorts = array(
      array(
        'field' => t('Task ID'),
        'sort' => 'desc',
        'first' => 'perform at superbowl',
        'last' => 'eat',
      ),
      array(
        'field' => t('Task ID'),
        'sort' => 'asc',
        'first' => 'eat',
        'last' => 'perform at superbowl',
      ),
      array(
        'field' => t('Task'),
        'sort' => 'asc',
        'first' => 'code',
        'last' => 'sleep',
      ),
      array(
        'field' => t('Task'),
        'sort' => 'desc',
        'first' => 'sleep',
        'last' => 'code',
      ),
    );
    foreach ($sorts as $sort) {
      $this
        ->drupalGet('database_test/tablesort_first/', array(
        'query' => array(
          'order' => $sort['field'],
          'sort' => $sort['sort'],
        ),
      ));
      $data = json_decode($this
        ->drupalGetContent());
      $first = array_shift($data->tasks);
      $last = array_pop($data->tasks);
      $this
        ->assertEqual($first->task, $sort['first'], t('Items appear in the correct order sorting by @field @sort.', array(
        '@field' => $sort['field'],
        '@sort' => $sort['sort'],
      )));
      $this
        ->assertEqual($last->task, $sort['last'], t('Items appear in the correct order sorting by @field @sort.', array(
        '@field' => $sort['field'],
        '@sort' => $sort['sort'],
      )));
    }
  }
}
class DatabaseTaggingTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Query tagging tests',
      'description' => 'Test the tagging capabilities of the Select builder.',
      'group' => 'Database',
    );
  }
  
  function testHasTag() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $query
      ->addTag('test');
    $this
      ->assertTrue($query
      ->hasTag('test'), t('hasTag() returned true.'));
    $this
      ->assertFalse($query
      ->hasTag('other'), t('hasTag() returned false.'));
  }
  
  function testHasAllTags() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $query
      ->addTag('test');
    $query
      ->addTag('other');
    $this
      ->assertTrue($query
      ->hasAllTags('test', 'other'), t('hasAllTags() returned true.'));
    $this
      ->assertFalse($query
      ->hasAllTags('test', 'stuff'), t('hasAllTags() returned false.'));
  }
  
  function testHasAnyTag() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $query
      ->addTag('test');
    $this
      ->assertTrue($query
      ->hasAnyTag('test', 'other'), t('hasAnyTag() returned true.'));
    $this
      ->assertFalse($query
      ->hasAnyTag('other', 'stuff'), t('hasAnyTag() returned false.'));
  }
  
  function testMetaData() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $data = array(
      'a' => 'A',
      'b' => 'B',
    );
    $query
      ->addMetaData('test', $data);
    $return = $query
      ->getMetaData('test');
    $this
      ->assertEqual($data, $return, t('Corect metadata returned.'));
    $return = $query
      ->getMetaData('nothere');
    $this
      ->assertNull($return, t('Non-existent key returned NULL.'));
  }
}
class DatabaseAlterTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Query altering tests',
      'description' => 'Test the hook_query_alter capabilities of the Select builder.',
      'group' => 'Database',
    );
  }
  
  function testSimpleAlter() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $query
      ->addTag('database_test_alter_add_range');
    $result = $query
      ->execute();
    $num_records = 0;
    foreach ($result as $record) {
      $num_records++;
    }
    $this
      ->assertEqual($num_records, 2, t('Returned the correct number of rows.'));
  }
  
  function testAlterWithJoin() {
    $query = db_select('test_task');
    $tid_field = $query
      ->addField('test_task', 'tid');
    $task_field = $query
      ->addField('test_task', 'task');
    $query
      ->orderBy($task_field);
    $query
      ->addTag('database_test_alter_add_join');
    $result = $query
      ->execute();
    $records = $result
      ->fetchAll();
    $this
      ->assertEqual(count($records), 2, t('Returned the correct number of rows.'));
    $this
      ->assertEqual($records[0]->name, 'George', t('Correct data retrieved.'));
    $this
      ->assertEqual($records[0]->{$tid_field}, 4, t('Correct data retrieved.'));
    $this
      ->assertEqual($records[0]->{$task_field}, 'sing', t('Correct data retrieved.'));
    $this
      ->assertEqual($records[1]->name, 'George', t('Correct data retrieved.'));
    $this
      ->assertEqual($records[1]->{$tid_field}, 5, t('Correct data retrieved.'));
    $this
      ->assertEqual($records[1]->{$task_field}, 'sleep', t('Correct data retrieved.'));
  }
  
  function testAlterChangeConditional() {
    $query = db_select('test_task');
    $tid_field = $query
      ->addField('test_task', 'tid');
    $pid_field = $query
      ->addField('test_task', 'pid');
    $task_field = $query
      ->addField('test_task', 'task');
    $people_alias = $query
      ->join('test', 'people', "test_task.pid = people.id");
    $name_field = $query
      ->addField($people_alias, 'name', 'name');
    $query
      ->condition('test_task.tid', '1');
    $query
      ->orderBy($tid_field);
    $query
      ->addTag('database_test_alter_change_conditional');
    $result = $query
      ->execute();
    $records = $result
      ->fetchAll();
    $this
      ->assertEqual(count($records), 1, t('Returned the correct number of rows.'));
    $this
      ->assertEqual($records[0]->{$name_field}, 'John', t('Correct data retrieved.'));
    $this
      ->assertEqual($records[0]->{$tid_field}, 2, t('Correct data retrieved.'));
    $this
      ->assertEqual($records[0]->{$pid_field}, 1, t('Correct data retrieved.'));
    $this
      ->assertEqual($records[0]->{$task_field}, 'sleep', t('Correct data retrieved.'));
  }
}
class DatabaseAlter2TestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Query altering tests, part 2',
      'description' => 'Test the hook_query_alter capabilities of the Select builder.',
      'group' => 'Database',
    );
  }
  
  function testAlterChangeFields() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addField('test', 'age', 'age');
    $query
      ->orderBy('name');
    $query
      ->addTag('database_test_alter_change_fields');
    $record = $query
      ->execute()
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Correct data retrieved.'));
    $this
      ->assertFalse(isset($record->{$age_field}), t('Age field not found, as intended.'));
  }
  
  function testAlterExpression() {
    $query = db_select('test');
    $name_field = $query
      ->addField('test', 'name');
    $age_field = $query
      ->addExpression("age*2", 'double_age');
    $query
      ->condition('age', 27);
    $query
      ->addTag('database_test_alter_change_expressions');
    $result = $query
      ->execute();
    
    $record = $result
      ->fetch();
    $this
      ->assertEqual($record->{$name_field}, 'George', t('Fetched name is correct.'));
    $this
      ->assertEqual($record->{$age_field}, 27 * 3, t('Fetched age expression is correct.'));
  }
  
  function testAlterRemoveRange() {
    $query = db_select('test');
    $query
      ->addField('test', 'name');
    $query
      ->addField('test', 'age', 'age');
    $query
      ->range(0, 2);
    $query
      ->addTag('database_test_alter_remove_range');
    $num_records = count($query
      ->execute()
      ->fetchAll());
    $this
      ->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
  }
}
class DatabaseRegressionTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Regression tests',
      'description' => 'Regression tests cases for the database layer.',
      'group' => 'Database',
    );
  }
  
  function testRegression_310447() {
    
    $name = str_repeat("é", 255);
    db_insert('test')
      ->fields(array(
      'name' => $name,
      'age' => 20,
      'job' => 'Dancer',
    ))
      ->execute();
    $from_database = db_query('SELECT name FROM {test} WHERE name = :name', array(
      ':name' => $name,
    ))
      ->fetchField();
    $this
      ->assertIdentical($name, $from_database, t("The database handles UTF-8 characters cleanly."));
  }
  
  function testDBColumnExists() {
    $this
      ->assertTrue(db_column_exists('node', 'nid'), t('Returns true for existent column.'));
    $this
      ->assertFalse(db_column_exists('node', 'nosuchcolumn'), t('Returns false for nonexistent column.'));
  }
  
  function testDBTableExists() {
    $this
      ->assertTrue(db_table_exists('node'), t('Returns true for existent table.'));
    $this
      ->assertFalse(db_table_exists('nosuchtable'), t('Returns false for nonexistent table.'));
  }
}
class DatabaseLoggingTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Query logging',
      'description' => 'Test the query logging facility.',
      'group' => 'Database',
    );
  }
  
  function testEnableLogging() {
    Database::startLog('testing');
    db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ))
      ->fetchCol();
    db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetchCol();
    $queries = Database::getLog('testing', 'default');
    $this
      ->assertEqual(count($queries), 2, t('Correct number of queries recorded.'));
    foreach ($queries as $query) {
      $this
        ->assertEqual($query['caller']['function'], __FUNCTION__, t('Correct function in query log.'));
    }
  }
  
  function testEnableMultiLogging() {
    Database::startLog('testing1');
    db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ))
      ->fetchCol();
    Database::startLog('testing2');
    db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ))
      ->fetchCol();
    $queries1 = Database::getLog('testing1');
    $queries2 = Database::getLog('testing2');
    $this
      ->assertEqual(count($queries1), 2, t('Correct number of queries recorded for log 1.'));
    $this
      ->assertEqual(count($queries2), 1, t('Correct number of queries recorded for log 2.'));
  }
  
  function testEnableTargetLogging() {
    
    $connection_info = Database::getConnectionInfo('default');
    Database::addConnectionInfo('default', 'slave', $connection_info['default']);
    Database::startLog('testing1');
    db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ))
      ->fetchCol();
    db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ), array(
      'target' => 'slave',
    ));
    
    $queries1 = Database::getLog('testing1');
    $this
      ->assertEqual(count($queries1), 2, t('Recorded queries from all targets.'));
    $this
      ->assertEqual($queries1[0]['target'], 'default', t('First query used default target.'));
    $this
      ->assertEqual($queries1[1]['target'], 'slave', t('Second query used slave target.'));
  }
  
  function testEnableTargetLoggingNoTarget() {
    Database::startLog('testing1');
    db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ))
      ->fetchCol();
    
    db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ), array(
      'target' => 'fake',
    ))
      ->fetchCol();
    $queries1 = Database::getLog('testing1');
    $this
      ->assertEqual(count($queries1), 2, t('Recorded queries from all targets.'));
    $this
      ->assertEqual($queries1[0]['target'], 'default', t('First query used default target.'));
    $this
      ->assertEqual($queries1[1]['target'], 'default', t('Second query used default target as fallback.'));
  }
  
  function testEnableMultiConnectionLogging() {
    
    $connection_info = Database::getConnectionInfo('default');
    Database::addConnectionInfo('test2', 'default', $connection_info['default']);
    Database::startLog('testing1');
    Database::startLog('testing1', 'test2');
    db_query('SELECT name FROM {test} WHERE age > :age', array(
      ':age' => 25,
    ))
      ->fetchCol();
    $old_key = db_set_active('test2');
    db_query('SELECT age FROM {test} WHERE name = :name', array(
      ':name' => 'Ringo',
    ), array(
      'target' => 'slave',
    ))
      ->fetchCol();
    db_set_active($old_key);
    $queries1 = Database::getLog('testing1');
    $queries2 = Database::getLog('testing1', 'test2');
    $this
      ->assertEqual(count($queries1), 1, t('Correct number of queries recorded for first connection.'));
    $this
      ->assertEqual(count($queries2), 1, t('Correct number of queries recorded for second connection.'));
  }
}
class DatabaseRangeQueryTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Range query test',
      'description' => 'Test the Range query functionality.',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp('database_test');
  }
  
  function testRangeQuery() {
    
    $range_rows = db_query_range("SELECT name FROM {system} ORDER BY name", 2, 3)
      ->fetchAll();
    $this
      ->assertEqual(count($range_rows), 3, t('Range query work and return correct number of rows.'));
    
    $raw_rows = db_query('SELECT name FROM {system} ORDER BY name')
      ->fetchAll();
    $raw_rows = array_slice($raw_rows, 2, 3);
    $this
      ->assertEqual($range_rows, $raw_rows, t('Range query work and return target data.'));
  }
}
class DatabaseTemporaryQueryTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Temporary query test',
      'description' => 'Test the temporary query functionality.',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp('database_test');
  }
  
  function countTableRows($table_name) {
    return db_select($table_name)
      ->countQuery()
      ->execute()
      ->fetchField();
  }
  
  function testTemporaryQuery() {
    $this
      ->drupalGet('database_test/db_query_temporary');
    $data = json_decode($this
      ->drupalGetContent());
    if ($data) {
      $this
        ->assertEqual($this
        ->countTableRows("system"), $data->row_count, t('The temporary table contains the correct amount of rows.'));
      $this
        ->assertFalse(db_table_exists($data->table_name), t('The temporary table is, indeed, temporary.'));
    }
    else {
      $this
        ->fail(t("The creation of the temporary table failed."));
    }
    
    $table_name_system = db_query_temporary('SELECT status FROM {system}', array());
    $table_name_users = db_query_temporary('SELECT uid FROM {users}', array());
    $this
      ->assertEqual($this
      ->countTableRows($table_name_system), $this
      ->countTableRows("system"), t('A temporary table was created successfully in this request.'));
    $this
      ->assertEqual($this
      ->countTableRows($table_name_users), $this
      ->countTableRows("users"), t('A second temporary table was created successfully in this request.'));
  }
}
class DatabaseAnsiSyntaxTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'ANSI SQL syntax tests',
      'description' => 'Test ANSI SQL syntax interpretation.',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp('database_test');
  }
  
  function testBasicConcat() {
    $result = db_query('SELECT :a1 || :a2 || :a3 || :a4 || :a5', array(
      ':a1' => 'This',
      ':a2' => ' ',
      ':a3' => 'is',
      ':a4' => ' a ',
      ':a5' => 'test.',
    ));
    $this
      ->assertIdentical($result
      ->fetchField(), 'This is a test.', t('Basic ANSI Concat works.'));
  }
  
  function testFieldConcat() {
    $result = db_query('SELECT :a1 || name || :a2 || age || :a3 FROM {test} WHERE age = :age', array(
      ':a1' => 'The age of ',
      ':a2' => ' is ',
      ':a3' => '.',
      ':age' => 25,
    ));
    $this
      ->assertIdentical($result
      ->fetchField(), 'The age of John is 25.', t('Field ANSI Concat works.'));
  }
}
class DatabaseInvalidDataTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Invalid data',
      'description' => 'Test handling of some invalid data.',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp('database_test');
  }
  
  function testInsertDuplicateData() {
    
    try {
      db_insert('test')
        ->fields(array(
        'name',
        'age',
        'job',
      ))
        ->values(array(
        'name' => 'Elvis',
        'age' => 63,
        'job' => 'Singer',
      ))
        ->values(array(
        'name' => 'John',
        
        'age' => 17,
        'job' => 'Consultant',
      ))
        ->values(array(
        'name' => 'Frank',
        'age' => 75,
        'job' => 'Singer',
      ))
        ->execute();
      $this
        ->fail(t('Insert succeedded when it should not have.'));
    } catch (Exception $e) {
      
      $name = db_query('SELECT name FROM {test} WHERE age = :age', array(
        ':age' => 63,
      ))
        ->fetchField();
      if ($name == 'Elvis') {
        if (!Database::getConnection()
          ->supportsTransactions()) {
          
          $this
            ->pass(t("The whole transaction has not been rolled-back when a duplicate key insert occurs, this is expected because the database doesn't support transactions"));
        }
        else {
          $this
            ->fail(t('The whole transaction is rolled back when a duplicate key insert occurs.'));
        }
      }
      else {
        $this
          ->pass(t('The whole transaction is rolled back when a duplicate key insert occurs.'));
      }
      
      $record = db_select('test')
        ->fields('test', array(
        'name',
        'age',
      ))
        ->condition('age', array(
        17,
        75,
      ), 'IN')
        ->execute()
        ->fetchObject();
      $this
        ->assertFalse($record, t('The rest of the insert aborted as expected.'));
    }
  }
}
class DatabaseQueryTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Custom query syntax tests',
      'description' => 'Test Drupal\'s extended prepared statement syntax..',
      'group' => 'Database',
    );
  }
  function setUp() {
    parent::setUp('database_test');
  }
  
  function testArraySubstitution() {
    $names = db_query('SELECT name FROM {test} WHERE age IN (:ages) ORDER BY age', array(
      ':ages' => array(
        25,
        26,
        27,
      ),
    ))
      ->fetchAll();
    $this
      ->assertEqual(count($names), 3, t('Correct number of names returned'));
  }
}
class DatabaseTransactionTestCase extends DatabaseTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Transaction tests',
      'description' => 'Test the transaction abstraction system.',
      'group' => 'Database',
    );
  }
  
  protected function transactionOuterLayer($suffix, $rollback = FALSE) {
    $connection = Database::getConnection();
    $txn = db_transaction();
    
    db_insert('test')
      ->fields(array(
      'name' => 'David' . $suffix,
      'age' => '24',
    ))
      ->execute();
    $this
      ->assertTrue($connection
      ->inTransaction(), t('In transaction before calling nested transaction.'));
    
    $this
      ->transactionInnerLayer($suffix, $rollback);
    $this
      ->assertTrue($connection
      ->inTransaction(), t('In transaction after calling nested transaction.'));
  }
  
  protected function transactionInnerLayer($suffix, $rollback = FALSE) {
    $connection = Database::getConnection();
    
    $txn = db_transaction();
    
    db_insert('test')
      ->fields(array(
      'name' => 'Daniel' . $suffix,
      'age' => '19',
    ))
      ->execute();
    $this
      ->assertTrue($connection
      ->inTransaction(), t('In transaction inside nested transaction.'));
    if ($rollback) {
      
      $txn
        ->rollback();
      $this
        ->assertTrue($txn
        ->willRollback(), t('Transaction is scheduled to roll back after calling rollback().'));
    }
  }
  
  function testTransactionsSupported() {
    try {
      $connection = Database::getConnection();
      if ($connection
        ->supportsTransactions()) {
        
        $txn = db_transaction(TRUE);
      }
      $this
        ->pass('Transaction started successfully.');
    } catch (TransactionsNotSupportedException $e) {
      $this
        ->fail("Exception thrown when it shouldn't have been.");
    }
  }
  
  function testTransactionsNotSupported() {
    try {
      $connection = Database::getConnection();
      if (!$connection
        ->supportsTransactions()) {
        
        $txn = db_transaction(TRUE);
        $this
          ->fail('No transaction failure registered.');
      }
    } catch (TransactionsNotSupportedException $e) {
      $this
        ->pass('Exception thrown for unsupported transactions.');
    }
  }
  
  function testTransactionRollBackSupported() {
    
    if (!Database::getConnection()
      ->supportsTransactions()) {
      return;
    }
    try {
      
      $this
        ->transactionOuterLayer('B', TRUE);
      
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DavidB',
      ))
        ->fetchField();
      $this
        ->assertNotIdentical($saved_age, '24', t('Cannot retrieve DavidB row after commit.'));
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DanielB',
      ))
        ->fetchField();
      $this
        ->assertNotIdentical($saved_age, '19', t('Cannot retrieve DanielB row after commit.'));
    } catch (Exception $e) {
      $this
        ->fail($e
        ->getMessage());
    }
  }
  
  function testTransactionRollBackNotSupported() {
    
    if (Database::getConnection()
      ->supportsTransactions()) {
      return;
    }
    try {
      
      $this
        ->transactionOuterLayer('B', TRUE);
      
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DavidB',
      ))
        ->fetchField();
      $this
        ->assertIdentical($saved_age, '24', t('DavidB not rolled back, since transactions are not supported.'));
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DanielB',
      ))
        ->fetchField();
      $this
        ->assertIdentical($saved_age, '19', t('DanielB not rolled back, since transactions are not supported.'));
    } catch (Exception $e) {
      $this
        ->fail($e
        ->getMessage());
    }
  }
  
  function testCommittedTransaction() {
    try {
      
      $this
        ->transactionOuterLayer('A');
      
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DavidA',
      ))
        ->fetchField();
      $this
        ->assertIdentical($saved_age, '24', t('Can retrieve DavidA row after commit.'));
      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(
        ':name' => 'DanielA',
      ))
        ->fetchField();
      $this
        ->assertIdentical($saved_age, '19', t('Can retrieve DanielA row after commit.'));
    } catch (Exception $e) {
      $this
        ->fail($e
        ->getMessage());
    }
  }
}
class DatabaseExtraTypesTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Extra Types tests',
      'description' => 'Test the Extra Types.',
      'group' => 'Database',
    );
  }
  
  function testDateField() {
    try {
      $date_table = array(
        'fields' => array(
          'date_field' => array(
            'description' => t('Test Date field'),
            'type' => 'date',
            'not null' => FALSE,
          ),
        ),
      );
      db_create_table('date_table', $date_table);
      $this
        ->assertTrue(db_table_exists('date_table'), t('Created table with date field'));
      db_insert('date_table')
        ->fields(array(
        'date_field',
      ))
        ->values(array(
        'date_field' => '2001-01-01',
      ))
        ->values(array(
        'date_field' => '1856-12-31',
      ))
        ->values(array(
        'date_field' => '2100-06-30',
      ))
        ->execute();
      $num_records = (int) db_query('SELECT COUNT(*) FROM {date_table}')
        ->fetchField();
      $this
        ->assertEqual($num_records, 3, t('Inserted 3 records, and counted 3 records'));
      $res = db_query('SELECT date_field from {date_table} ORDER BY date_field');
      $date = $res
        ->fetch()->date_field;
      $this
        ->assertEqual($date, '1856-12-31', t('Date retrieved in order @date', array(
        '@date' => $date,
      )));
      $date = $res
        ->fetch()->date_field;
      $this
        ->assertEqual($date, '2001-01-01', t('Date retrieved in order @date', array(
        '@date' => $date,
      )));
      $date = $res
        ->fetch()->date_field;
      $this
        ->assertEqual($date, '2100-06-30', t('Date retrieved in order @date', array(
        '@date' => $date,
      )));
      db_drop_table('date_table');
      $this
        ->assertFalse(db_table_exists('date_table'), t('Dropped table with date field'));
    } catch (Exception $e) {
      $this
        ->fail($e
        ->getMessage());
    }
  }
  
  function testTimeField() {
    try {
      $time_table = array(
        'fields' => array(
          'time_field' => array(
            'description' => t('Test Time field'),
            'type' => 'time',
            'not null' => FALSE,
          ),
        ),
      );
      db_create_table('time_table', $time_table);
      $this
        ->assertTrue(db_table_exists('time_table'), t('Created table with time field'));
      db_insert('time_table')
        ->fields(array(
        'time_field',
      ))
        ->values(array(
        'time_field' => '12:59:00',
      ))
        ->values(array(
        'time_field' => '00:01:00',
      ))
        ->values(array(
        'time_field' => '23:17:00',
      ))
        ->execute();
      $num_records = (int) db_query('SELECT COUNT(*) FROM {time_table}')
        ->fetchField();
      $this
        ->assertEqual($num_records, 3, t('Inserted 3 records, and counted 3 records'));
      $res = db_query('SELECT time_field from {time_table} ORDER BY time_field');
      $time = $res
        ->fetch()->time_field;
      $this
        ->assertEqual($time, '00:01:00', t('Time retrieved in order @time', array(
        '@time' => $time,
      )));
      $time = $res
        ->fetch()->time_field;
      $this
        ->assertEqual($time, '12:59:00', t('Time retrieved in order @time', array(
        '@time' => $time,
      )));
      $time = $res
        ->fetch()->time_field;
      $this
        ->assertEqual($time, '23:17:00', t('Time retrieved in order @time', array(
        '@time' => $time,
      )));
      db_drop_table('time_table');
      $this
        ->assertFalse(db_table_exists('time_table'), t('Dropped table with time field'));
    } catch (Exception $e) {
      $this
        ->fail($e
        ->getMessage());
    }
  }
}
class DatabaseNextIdCase extends DrupalWebTestCase {
  function getInfo() {
    return array(
      'name' => t('Sequences API'),
      'description' => t('Test the secondary sequences API.'),
      'group' => t('Database'),
    );
  }
  
  function testDbNextId() {
    $first = db_next_id();
    $second = db_next_id();
    
    $this
      ->assertEqual($first + 1, $second, t('The second call from a sequence provides a number increased by one.'));
    $result = db_next_id(1000);
    $this
      ->assertEqual($result, 1001, t('Sequence provides a larger number than the existing ID.'));
  }
}