Created
March 14, 2021 17:39
-
-
Save robske110/a941e7dba8f9906e90df9fede2d3861a to your computer and use it in GitHub Desktop.
Easy to use dynamic SQL table copier
This file contains hidden or 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 | |
// 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