Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Less sprintf in adapters #788

Merged
merged 13 commits into from
Dec 17, 2024
6 changes: 6 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ parameters:
count: 1
path: src/Db/Adapter/SqliteAdapter.php

-
message: '#^Strict comparison using \!\=\= between Cake\\Database\\StatementInterface and null will always evaluate to true\.$#'
identifier: notIdentical.alwaysTrue
count: 1
path: src/Db/Adapter/SqliteAdapter.php

-
message: '#^PHPDoc tag @return with type Phinx\\Db\\Adapter\\AdapterInterface is not subtype of native type Migrations\\Db\\Adapter\\AdapterInterface\.$#'
identifier: return.phpDocType
Expand Down
67 changes: 36 additions & 31 deletions src/Db/Adapter/MysqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -751,19 +751,22 @@ public function hasPrimaryKey(string $tableName, $columns, ?string $constraint =
public function getPrimaryKey(string $tableName): array
{
$options = $this->getOptions();
$rows = $this->fetchAll(sprintf(
$params = [
$options['database'],
$tableName,
];
$rows = $this->query(
"SELECT
k.CONSTRAINT_NAME,
k.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE k
USING(CONSTRAINT_NAME,TABLE_SCHEMA,TABLE_NAME)
WHERE t.CONSTRAINT_TYPE='PRIMARY KEY'
AND t.TABLE_SCHEMA='%s'
AND t.TABLE_NAME='%s'",
$options['database'],
$tableName
));
WHERE t.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND t.TABLE_SCHEMA = ?
AND t.TABLE_NAME = ?",
$params
)->fetchAll('assoc');

$primaryKey = [
'columns' => [],
Expand Down Expand Up @@ -809,26 +812,33 @@ public function hasForeignKey(string $tableName, $columns, ?string $constraint =
*/
protected function getForeignKeys(string $tableName): array
{
$schema = null;
if (strpos($tableName, '.') !== false) {
[$schema, $tableName] = explode('.', $tableName);
}

$foreignKeys = [];
$rows = $this->fetchAll(sprintf(
"SELECT
$params = [];
$query = "SELECT
CONSTRAINT_NAME,
CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS TABLE_NAME,
COLUMN_NAME,
CONCAT(REFERENCED_TABLE_SCHEMA, '.', REFERENCED_TABLE_NAME) AS REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME IS NOT NULL
AND TABLE_SCHEMA = %s
AND TABLE_NAME = '%s'
ORDER BY POSITION_IN_UNIQUE_CONSTRAINT",
empty($schema) ? 'DATABASE()' : "'$schema'",
$tableName
));
WHERE REFERENCED_TABLE_NAME IS NOT NULL";

if ($schema) {
$query .= ' AND TABLE_SCHEMA = ?';
$params[] = $schema;
} else {
$query .= ' AND TABLE_SCHEMA = DATABASE()';
}

$query .= ' AND TABLE_NAME = ? ORDER BY POSITION_IN_UNIQUE_CONSTRAINT';
$params[] = $tableName;

$foreignKeys = [];
$rows = $this->query($query, $params)->fetchAll('assoc');
foreach ($rows as $row) {
$foreignKeys[$row['CONSTRAINT_NAME']]['table'] = $row['TABLE_NAME'];
$foreignKeys[$row['CONSTRAINT_NAME']]['columns'][] = $row['COLUMN_NAME'];
Expand Down Expand Up @@ -1270,12 +1280,10 @@ public function createDatabase(string $name, array $options = []): void
*/
public function hasDatabase(string $name): bool
{
$rows = $this->fetchAll(
sprintf(
'SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = \'%s\'',
$name
)
);
$rows = $this->query(
'SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?',
[$name]
)->fetchAll('assoc');

foreach ($rows as $row) {
if (!empty($row)) {
Expand Down Expand Up @@ -1470,16 +1478,13 @@ public function describeTable(string $tableName): array
$options = $this->getOptions();

// mysql specific
$sql = sprintf(
"SELECT *
$sql = "SELECT *
FROM information_schema.tables
WHERE table_schema = '%s'
AND table_name = '%s'",
$options['database'],
$tableName
);
WHERE table_schema = ?
AND table_name = ?";
$params = [$options['database'], $tableName];

$table = $this->fetchRow($sql);
$table = $this->query($sql, $params)->fetch('assoc');

return $table !== false ? $table : [];
}
Expand Down
38 changes: 22 additions & 16 deletions src/Db/Adapter/PdoAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,31 +479,33 @@ public function migrated(MigrationInterface $migration, string $direction, strin
if (strcasecmp($direction, MigrationInterface::UP) === 0) {
// up
$sql = sprintf(
"INSERT INTO %s (%s, %s, %s, %s, %s) VALUES ('%s', '%s', '%s', '%s', %s);",
'INSERT INTO %s (%s, %s, %s, %s, %s) VALUES (?, ?, ?, ?, ?);',
$this->quoteTableName($this->getSchemaTableName()),
$this->quoteColumnName('version'),
$this->quoteColumnName('migration_name'),
$this->quoteColumnName('start_time'),
$this->quoteColumnName('end_time'),
$this->quoteColumnName('breakpoint'),
);
$params = [
$migration->getVersion(),
substr($migration->getName(), 0, 100),
$startTime,
$endTime,
$this->castToBool(false)
);
$this->castToBool(false),
];

$this->execute($sql);
$this->execute($sql, $params);
} else {
// down
$sql = sprintf(
"DELETE FROM %s WHERE %s = '%s'",
'DELETE FROM %s WHERE %s = ?',
$this->quoteTableName($this->getSchemaTableName()),
$this->quoteColumnName('version'),
$migration->getVersion()
);
$params = [$migration->getVersion()];

$this->execute($sql);
$this->execute($sql, $params);
}

return $this;
Expand All @@ -514,17 +516,18 @@ public function migrated(MigrationInterface $migration, string $direction, strin
*/
public function toggleBreakpoint(MigrationInterface $migration): AdapterInterface
{
$params = [
$migration->getVersion(),
];
$this->query(
sprintf(
'UPDATE %1$s SET %2$s = CASE %2$s WHEN %3$s THEN %4$s ELSE %3$s END, %7$s = %7$s WHERE %5$s = \'%6$s\';',
'UPDATE %1$s SET %2$s = CASE %2$s WHEN true THEN false ELSE true END, %4$s = %4$s WHERE %3$s = ?;',
$this->quoteTableName($this->getSchemaTableName()),
$this->quoteColumnName('breakpoint'),
$this->castToBool(true),
$this->castToBool(false),
$this->quoteColumnName('version'),
$migration->getVersion(),
$this->quoteColumnName('start_time')
)
),
$params
);

return $this;
Expand Down Expand Up @@ -575,16 +578,19 @@ public function unsetBreakpoint(MigrationInterface $migration): AdapterInterface
*/
protected function markBreakpoint(MigrationInterface $migration, bool $state): AdapterInterface
{
$params = [
$this->castToBool($state),
$migration->getVersion(),
];
$this->query(
sprintf(
'UPDATE %1$s SET %2$s = %3$s, %4$s = %4$s WHERE %5$s = \'%6$s\';',
'UPDATE %1$s SET %2$s = ?, %3$s = %3$s WHERE %4$s = ?;',
$this->quoteTableName($this->getSchemaTableName()),
$this->quoteColumnName('breakpoint'),
$this->castToBool($state),
$this->quoteColumnName('start_time'),
$this->quoteColumnName('version'),
$migration->getVersion()
)
),
$params
);

return $this;
Expand Down
54 changes: 27 additions & 27 deletions src/Db/Adapter/PostgresAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,16 +496,15 @@ protected function getRenameColumnInstructions(
string $newColumnName
): AlterInstructions {
$parts = $this->getSchemaName($tableName);
$sql = sprintf(
'SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS column_exists
$sql = 'SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS column_exists
FROM information_schema.columns
WHERE table_schema = %s AND table_name = %s AND column_name = %s',
$this->quoteString($parts['schema']),
$this->quoteString($parts['table']),
$this->quoteString($columnName)
);

$result = $this->fetchRow($sql);
WHERE table_schema = ? AND table_name = ? AND column_name = ?';
$params = [
$parts['schema'],
$parts['table'],
$columnName,
];
$result = $this->query($sql, $params)->fetch('assoc');
if (!$result || !(bool)$result['column_exists']) {
throw new InvalidArgumentException("The specified column does not exist: $columnName");
}
Expand Down Expand Up @@ -833,20 +832,23 @@ public function hasPrimaryKey(string $tableName, $columns, ?string $constraint =
public function getPrimaryKey(string $tableName): array
{
$parts = $this->getSchemaName($tableName);
$rows = $this->fetchAll(sprintf(
$params = [
$parts['schema'],
$parts['table'],
];
$rows = $this->query(
"SELECT
tc.constraint_name,
kcu.column_name
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
WHERE constraint_type = 'PRIMARY KEY'
AND tc.table_schema = %s
AND tc.table_name = %s
AND tc.table_schema = ?
AND tc.table_name = ?
ORDER BY kcu.position_in_unique_constraint",
$this->quoteString($parts['schema']),
$this->quoteString($parts['table'])
));
$params,
)->fetchAll('assoc');

$primaryKey = [
'columns' => [],
Expand Down Expand Up @@ -896,7 +898,11 @@ protected function getForeignKeys(string $tableName): array
{
$parts = $this->getSchemaName($tableName);
$foreignKeys = [];
$rows = $this->fetchAll(sprintf(
$params = [
$parts['schema'],
$parts['table'],
];
$rows = $this->query(
"SELECT
tc.constraint_name,
tc.table_name, kcu.column_name,
Expand All @@ -906,11 +912,10 @@ protected function getForeignKeys(string $tableName): array
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' AND tc.table_schema = %s AND tc.table_name = %s
WHERE constraint_type = 'FOREIGN KEY' AND tc.table_schema = ? AND tc.table_name = ?
ORDER BY kcu.ordinal_position",
$this->quoteString($parts['schema']),
$this->quoteString($parts['table'])
));
$params,
)->fetchAll('assoc');
foreach ($rows as $row) {
$foreignKeys[$row['constraint_name']]['table'] = $row['table_name'];
$foreignKeys[$row['constraint_name']]['columns'][] = $row['column_name'];
Expand Down Expand Up @@ -1384,13 +1389,8 @@ public function createSchema(string $schemaName = 'public'): void
*/
public function hasSchema(string $schemaName): bool
{
$sql = sprintf(
'SELECT count(*)
FROM pg_namespace
WHERE nspname = %s',
$this->quoteString($schemaName)
);
$result = $this->fetchRow($sql);
$sql = 'SELECT count(*) FROM pg_namespace WHERE nspname = ?';
$result = $this->query($sql, [$schemaName])->fetch('assoc');
if (!$result) {
return false;
}
Expand Down
34 changes: 20 additions & 14 deletions src/Db/Adapter/SqliteAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,16 @@ protected function resolveTable(string $tableName): array
} else {
$master = sprintf('%s.%s', $this->quoteColumnName($schema), 'sqlite_master');
}
$rows = [];
try {
$rows = $this->fetchAll(sprintf("SELECT name FROM %s WHERE type='table' AND lower(name) = %s", $master, $this->quoteString($table)));
$result = $this->query(
"SELECT name FROM {$master} WHERE type = 'table' AND lower(name) = ?",
[$table]
);
// null on error
if ($result !== null) {
$rows = $result->fetchAll('assoc');
}
} catch (PDOException $e) {
// an exception can occur if the schema part of the table refers to a database which is not attached
break;
Expand Down Expand Up @@ -797,19 +805,17 @@ protected function bufferIndicesAndTriggers(AlterInstructions $instructions, str
$state['indices'] = [];
$state['triggers'] = [];

$rows = $this->fetchAll(
sprintf(
"
SELECT *
FROM sqlite_master
WHERE
(`type` = 'index' OR `type` = 'trigger')
AND tbl_name = %s
AND sql IS NOT NULL
",
$this->quoteValue($tableName)
)
);
$params = [$tableName];
$rows = $this->query(
"SELECT *
FROM sqlite_master
WHERE
(`type` = 'index' OR `type` = 'trigger')
AND tbl_name = ?
AND sql IS NOT NULL
",
$params
)->fetchAll('assoc');

$schema = $this->getSchemaName($tableName, true)['schema'];

Expand Down
Loading
Loading