Skip to content

Commit

Permalink
Implemented simple insert and update commands in Connection class
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Jul 2, 2012
1 parent f5dc294 commit 9cd7aba
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 2 deletions.
51 changes: 49 additions & 2 deletions lib/Cake/Model/Datasource/Database/Connection.php
Expand Up @@ -144,7 +144,17 @@ public function query($sql) {
* @return Cake\Model\Datasource\Database\Statement
**/
public function insert($table, array $data, array $types = array()) {

$this->connect();
$keys = array_keys($data);
$sql = 'INSERT INTO %s (%s) VALUES (%s)';
$sql = sprintf(
$sql,
$table,
implode(',', $keys),
implode(',', array_fill(0, count($data), '?'))
);
$types = $this->_mapTypes($keys, $types);
return $this->execute($sql, array_values($data), $types);
}

/**
Expand All @@ -157,7 +167,20 @@ public function insert($table, array $data, array $types = array()) {
* @return Cake\Model\Datasource\Database\Statement
**/
public function update($table, array $data, array $conditions = array(), $types = array()) {

$this->connect();
$keys = array_keys($data);
$sql = 'UPDATE %s SET %s %s';
list($conditions, $params) = $this->_parseConditions($conditions);
$sql = sprintf(
$sql,
$table,
rtrim(',', implode(' = ?,', $keys)),
$conditions
);
if (!empty($type)) {
$types = $this->_mapTypes($keys, $types);
}
return $this->execute($sql, array_values($data), $types);
}

/**
Expand Down Expand Up @@ -267,4 +290,28 @@ protected function _bindValues($statement, $params, $types) {
}
}

protected function _mapTypes($columns, $types) {
if (!is_int(key($types))) {
$positons = array_intersect_key(array_flip($columns), $types);
$types = array_combine($positons, $types);
}
return $types;
}

protected function _parseConditions($conditions) {
$params = array();
if (empty($conditions)) {
return array('', $params);
}
$sql = 'WHERE %s';
$conds = array();
foreach ($conditions as $key => $value) {
if (is_numeric($key)) {
$conds[] = $value;
continue;
}
$conds[] = $key . ' = ';
}
}

}
Expand Up @@ -31,6 +31,10 @@ public function setUp() {
$this->connection = new Connection(Configure::read('Connections.test'));
}

public function tearDown() {
$this->connection->execute('DROP TABLE IF EXISTS things');
}

/**
* Tests connecting to database
*
Expand Down Expand Up @@ -166,4 +170,93 @@ public function testExecuteWithNoParams() {
$this->assertEquals(array(1), $result);
}

/**
* Tests it is possible to insert data into a table using matching types by key name
*
* @return void
**/
public function testInsertWithMatchingTypes() {
$table = 'CREATE TEMPORARY TABLE things(id int, title varchar(20), body varchar(50))';
$this->connection->execute($table);
$data = array('id' => '1', 'title' => 'a title', 'body' => 'a body');
$result = $this->connection->insert(
'things',
$data,
array('id' => 'integer', 'title' => 'string', 'body' => 'string')
);
$this->assertInstanceOf('Cake\Model\Datasource\Database\Statement', $result);
$result = $this->connection->execute('SELECT * from things');
$this->assertCount(1, $result);
$row = $result->fetch('assoc');
$this->assertEquals($data, $row);
}

/**
* Tests it is possible to insert data into a table using matching types by array position
*
* @return void
**/
public function testInsertWithPositionalTypes() {
$table = 'CREATE TEMPORARY TABLE things(id int, title varchar(20), body varchar(50))';
$this->connection->execute($table);
$data = array('id' => '1', 'title' => 'a title', 'body' => 'a body');
$result = $this->connection->insert(
'things',
$data,
array('integer', 'string', 'string')
);
$this->assertInstanceOf('Cake\Model\Datasource\Database\Statement', $result);
$result = $this->connection->execute('SELECT * from things');
$this->assertCount(1, $result);
$row = $result->fetch('assoc');
$this->assertEquals($data, $row);
}

protected function _insertTwoRecords() {
$table = 'CREATE TEMPORARY TABLE things(id int, title varchar(20), body varchar(50))';
$this->connection->execute($table);
$data = array('id' => '1', 'title' => 'a title', 'body' => 'a body');
$result = $this->connection->insert(
'things',
$data,
array('id' => 'integer', 'title' => 'string', 'body' => 'string')
);

$result->bindValue(1, '2', 'integer');
$result->bindValue(2, 'another title');
$result->bindValue(3, 'another body');
$result->execute();
}

/**
* Tests an statement class can be reused for multiple executions
*
* @return void
**/
public function testStatementReusing() {
$this->_insertTwoRecords();

$total = $this->connection->execute('SELECT COUNT(*) AS total FROM things');
$total = $total->fetch('assoc');
$this->assertEquals(2, $total['total']);

$result = $this->connection->execute('SELECT title, body FROM things');
$row = $result->fetch('assoc');
$this->assertEquals('a title', $row['title']);
$this->assertEquals('a body', $row['body']);

$row = $result->fetch('assoc');
$this->assertEquals('another title', $row['title']);
$this->assertEquals('another body', $row['body']);
}

public function testUpdateWithoutConditionsNorTypes() {
$this->_insertTwoRecords();
$title = 'changed the title!';
$body = 'changed the body!';
$this->connection->update('things', array('title' => $title, 'body' => $body));
$result = $this->connection->execute('SELECT * FROM things WHERE title = ? AND body = ?', array($title, $body));
$this->assertCount(2, $result);
}

}

0 comments on commit 9cd7aba

Please sign in to comment.