Created
March 15, 2012 14:59
-
-
Save hakre/2044649 to your computer and use it in GitHub Desktop.
Large insert query SQL builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @link http://stackoverflow.com/questions/9719032/php-insert-array-into-db-i-know-there-already-posts-existing-but | |
*/ | |
/** | |
* Insert Query SQL Builder based on packed size limits | |
*/ | |
class SQLInsertQuery | |
{ | |
/** | |
* @var string | |
*/ | |
private $base; | |
/** | |
* @var string | |
*/ | |
private $sql; | |
/** | |
* @var int | |
*/ | |
private $delta; | |
/** | |
* @var int | |
*/ | |
private $limit; | |
/** | |
* @var int | |
*/ | |
private $count; | |
/** | |
* @param string $base | |
* @param int $limit | |
* @param int $delta additional bytes for length calculation | |
*/ | |
public function __construct($base, $limit, $delta = 10) { | |
$this->base = $base; | |
$this->limit = $limit; | |
$this->delta = $delta; | |
$this->resetQuery(); | |
} | |
public function resetQuery() { | |
$this->sql = $this->base; | |
$this->count = 0; | |
} | |
/** | |
* @param string $sqlFragment | |
* @return bool | |
*/ | |
public function willQuery($sqlFragment) { | |
return $this->isAboveLimit($this->sql . $sqlFragment); | |
} | |
/** | |
* @param string $sql | |
* @return bool | |
*/ | |
private function isAboveLimit($sql) { | |
return strlen($sql) + $this->delta > $this->limit; | |
} | |
/** | |
* @param string $sql | |
*/ | |
public function addSQL($sql) { | |
$separator = ','; | |
if ($this->willQuery($sql)) { | |
$this->query(); | |
} | |
if ($this->count++) $sql = $separator . $sql; | |
$this->sql .= $sql; | |
} | |
public function query() { | |
if (!$this->count) { | |
return; # nothing to do | |
} | |
$sql = $this->sql . ';'; | |
// do your mysql query here. | |
printf("Running: %s\n", $sql); | |
$this->resetQuery(); | |
} | |
/** | |
* @param array $row | |
*/ | |
public function addRow(array $row) { | |
$values = $this->encodeRow($row); | |
$pair = $this->buildPair($values); | |
$this->addSQL($pair); | |
} | |
private function encodeRow(array $row) { | |
foreach($row as &$value) { | |
// e.g.: | |
// $value = sprintf("'%s'", mysqli_real_escape_string($value)); | |
// according to the row value types. | |
$value = sprintf("'%s'", $value); # this example is w/o mysqli | |
} | |
unset($value); | |
return $row; | |
} | |
private function buildPair($values) { | |
return sprintf('(%s)', implode(',', $values)); | |
} | |
} | |
# sample data | |
$data = array( | |
array('city1', 'code', 'country'), | |
array('city2', 'code', 'country'), | |
array('city3', 'code', 'country'), | |
array('city4', 'code', 'country'), | |
array('city5', 'code', 'country'), | |
array('city6', 'code', 'country'), | |
array('city7', 'code', 'country'), | |
); | |
$max_allowed_packet = 1048576; # mysql default value | |
$max_allowed_packet = 128; # for demonstration purposes | |
$sql = new SQLInsertQuery('INSERT INTO test (t_city, t_code, t_country) VALUES ', $max_allowed_packet); | |
foreach($data as $row) { # any iterator data-set provider does work | |
$sql->addRow($row); | |
} | |
$sql->query(); # manually query any potential left-over query. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment