Skip to content

Instantly share code, notes, and snippets.

@robske110
Created March 14, 2021 17:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robske110/a941e7dba8f9906e90df9fede2d3861a to your computer and use it in GitHub Desktop.
Save robske110/a941e7dba8f9906e90df9fede2d3861a to your computer and use it in GitHub Desktop.
Easy to use dynamic SQL table copier
<?php
// DynTableCopy
// Copyright robske_110 2021
declare(strict_types=1);
$dbConnectionConfig = [
"DB_SRC_HOST" => null,
"DB_SRC_NAME" => null,
"DB_SRC_USER" => null,
"DB_SRC_PASSWORD" => null,
"DB_SRC_DRIVER" => null,
"DB_DEST_HOST" => null,
"DB_DEST_NAME" => null,
"DB_DEST_USER" => null,
"DB_DEST_PASSWORD" => null,
"DB_DEST_DRIVER" => null,
];
$tableName = null; //ENV is DB_COPY_TABLE
$convertBooleanToInt = null; //ENV is CONVERT_BOOLEAN_TO_INT, set to "no" to disable
// -----
foreach($dbConnectionConfig as $key => $value){
if($key === null){
continue;
}
$_ENV[$key] = $value;
}
if($tableName !== null){
$_ENV["DB_COPY_TABLE"] = $tableName;
}
if($tableName !== null){
$_ENV["CONVERT_BOOLEAN_TO_INT"] = $convertBooleanToInt;
}
$required_envvars = ["DB_SRC_HOST", "DB_SRC_NAME", "DB_SRC_USER", "DB_DEST_HOST", "DB_DEST_NAME", "DB_DEST_USER", "DB_COPY_TABLE"];
foreach($required_envvars as $required_envvar){
if(!isset($_ENV[$required_envvar])){
echo("Error: required envvar ".$required_envvar." not set!\n");
exit;
}
}
$dbSrc = new DatabaseConnection(
$_ENV["DB_SRC_HOST"], $_ENV["DB_SRC_NAME"], $_ENV["DB_SRC_USER"], $_ENV["DB_SRC_PASSWORD"] ?? null,
$_ENV["DB_SRC_DRIVER"] ?? "pgsql"
);
$dbDest = new DatabaseConnection(
$_ENV["DB_DEST_HOST"], $_ENV["DB_DEST_NAME"], $_ENV["DB_DEST_USER"], $_ENV["DB_DEST_PASSWORD"] ?? null,
$_ENV["DB_DEST_DRIVER"] ?? "pgsql"
);
$data = $dbSrc->query("SELECT * FROM ".$tableName);
$keys = array_keys($data[0]);
$query = "INSERT INTO ".$tableName."(";
foreach($keys as $key){
$query .= $key.", ";
}
$query = substr($query, 0, strlen($query)-2);
$query .= ") VALUES(";
for($i = 1; $i < count($keys); ++$i){
$query .= "?, ";
}
$query .= "?) ";
$query .= QueryCreationHelper::createUpsert($_ENV["DB_DEST_DRIVER"] ?? "pgsql", $keys[0], $keys);
echo("Created insert query ".$query.PHP_EOL);
$insert = $dbDest->prepare($query);
echo("Now INSERTING ".count($data)." row(s)".PHP_EOL);
foreach($data as $row){
if($_ENV["CONVERT_BOOLEAN_TO_INT"] !== "no"){
foreach($row as $key => $val){
if(is_bool($val)){
$row[$key] = $val ? 1 : 0;
}
}
}
$insert->execute(array_values($row));
}
class QueryCreationHelper{
public static function createUpsert(string $driver, string $primaryKey, array $columns): string{
switch($driver){
case "pgsql":
return self::createPostgresUpsert($primaryKey, $columns);
default:
echo("CREATING UPSERT FOR NOT (EXPLICITLY) SUPPORTED DB DRIVER!".PHP_EOL);
case "mysql":
return self::createMySQLUpsert($primaryKey, $columns);
}
}
public static function createPostgresUpsert(string $primaryKey, array $columns): string{
$query = "ON CONFLICT (".$primaryKey.") DO UPDATE SET ";
foreach($columns as $column){
$query .= $column." = excluded.".$column.", ";
}
return substr($query, 0, strlen($query)-2);
}
public static function createMySQLUpsert(string $primaryKey, array $columns): string{
$query = "ON DUPLICATE KEY UPDATE ";
foreach($columns as $column){
$query .= $column." = VALUES(".$column."), ";
}
return substr($query, 0, strlen($query)-2);
}
}
class DatabaseConnection{
private PDO $connection;
private string $host;
private string $db;
private string $username;
private ?string $password;
private string $driver;
public function __construct(string $host, string $db, string $username, ?string $password = null, string $driver = "pgsql"){
$this->host = $host;
$this->db = $db;
$this->username = $username;
$this->password = $password;
$this->driver = $driver;
$this->connect();
}
public function connect(){
$this->connection = new PDO(
$this->driver.":host=".$this->host.";dbname=".$this->db, $this->username, $this->password
);
}
public function getConnection(): PDO{
return $this->connection;
}
public function query(string $sql): array{
$res = $this->connection->query($sql);
return $res->fetchAll(PDO::FETCH_ASSOC);
}
public function queryStatement(string $sql): PDOStatement{
return $this->connection->query($sql);
}
public function prepare(string $sql): PDOStatement{
return $this->connection->prepare($sql);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment