Skip to content

Commit

Permalink
Merge pull request #199 from nextras/readonly-schema
Browse files Browse the repository at this point in the history
Readonly schema
  • Loading branch information
hrach committed Feb 12, 2023
2 parents 0c62a78 + 371951a commit 38c038d
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 262 deletions.
26 changes: 13 additions & 13 deletions docs/param-modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@ $connection->query('WHERE [roles.privileges] ?| ARRAY[%...s[]]', ['backend', 'fr

Other available modifiers:

| Modifier | Description |
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `%and` | AND condition |
| `%or` | OR condition |
| `%multiOr` | OR condition with multiple conditions in pairs |
| `%values`, `%values[]` | expands array for INSERT clause, multi insert |
| `%set` | expands array for SET clause |
| `%table`, `%table[]` | escapes string as table name, may contain a database or schema name separated by a dot; surrounding parentheses are not added to `%table[]` modifier; |
| `%column`, `%column[]` | escapes string as column name, may contain a database name, schema name or asterisk (`*`) separated by a dot; surrounding parentheses are not added to `%column[]` modifier; |
| `%ex` | expands array as processor arguments |
| `%raw` | inserts string argument as is |
| `%%` | escapes to single `%` (useful in `date_format()`, etc.) |
| `[[`, `]]` | escapes to single `[` or `]` (useful when working with array, etc.) |
| Modifier | Description |
|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `%and` | AND condition |
| `%or` | OR condition |
| `%multiOr` | OR condition with multiple conditions in pairs |
| `%values`, `%values[]` | expands array for INSERT clause, multi insert |
| `%set` | expands array for SET clause |
| `%table`, `%table[]` | escapes string as table name, may contain a database or schema name separated by a dot; surrounding parentheses are not added to `%table[]` modifier; `%table` supports also processing a `Nextras\Dbal\Platforms\Data\Fqn` instance. |
| `%column`, `%column[]` | escapes string as column name, may contain a database name, schema name or asterisk (`*`) separated by a dot; surrounding parentheses are not added to `%column[]` modifier; |
| `%ex` | expands array as processor arguments |
| `%raw` | inserts string argument as is |
| `%%` | escapes to single `%` (useful in `date_format()`, etc.) |
| `[[`, `]]` | escapes to single `[` or `]` (useful when working with array, etc.) |

Let's examine `%and` and `%or` behavior. If array key is numeric and its value is an array, value is expanded with `%ex` modifier. (See below.)

Expand Down
30 changes: 17 additions & 13 deletions src/Platforms/Data/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ class Column
use StrictObjectTrait;


public string $name;
public string $type;
public ?int $size;
public ?string $default;
public bool $isPrimary;
public bool $isAutoincrement;
public bool $isUnsigned;
public bool $isNullable;
/**
* @var mixed[]
* @phpstan-var array<string, mixed>
*/
public array $meta = [];
public function __construct(
public readonly string $name,
public readonly string $type,
public readonly ?int $size,
public readonly ?string $default,
public readonly bool $isPrimary,
public readonly bool $isAutoincrement,
public readonly bool $isUnsigned,
public readonly bool $isNullable,
/**
* @var mixed[]
* @phpstan-var array<string, mixed>
*/
public array $meta = [],
)
{
}
}
30 changes: 6 additions & 24 deletions src/Platforms/Data/ForeignKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,12 @@ class ForeignKey
use StrictObjectTrait;


public string $name;
public string $schema;
public string $column;
public string $refTable;
public string $refTableSchema;
public string $refColumn;


public function getNameFqn(): string
{
if ($this->schema === '') {
return $this->name;
} else {
return "$this->schema.$this->name";
}
}


public function getRefTableFqn(): string
public function __construct(
public readonly Fqn $fqnName,
public readonly string $column,
public readonly Fqn $refTable,
public readonly string $refColumn,
)
{
if ($this->refTableSchema === '') {
return $this->refTable;
} else {
return "$this->refTableSchema.$this->refTable";
}
}
}
27 changes: 27 additions & 0 deletions src/Platforms/Data/Fqn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types = 1);

namespace Nextras\Dbal\Platforms\Data;


/**
* Fully qualified name/identifier
*/
class Fqn
{
public function __construct(
public readonly string $name,
public readonly string $schema,
)
{
}


public function getUnescaped(): string
{
if ($this->schema === '') {
return $this->name;
} else {
return "$this->schema.$this->name";
}
}
}
45 changes: 4 additions & 41 deletions src/Platforms/Data/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,10 @@ class Table
use StrictObjectTrait;


public string $name;
public string $schema;
public bool $isView;


/**
* @deprecated Use getUnescapedFqn()
*/
public function getNameFqn(): string
{
return $this->getUnescapedFqn();
}


/**
* Returns unescaped string expression with schema (database) name and table name.
*/
public function getUnescapedFqn(): string
{
if ($this->schema === '') {
return $this->name;
} else {
return "$this->schema.$this->name";
}
}


/**
* Returns Dbal's expression that will provide proper escaping for SQL usage.
* Use with %ex modifier:
* ```php
* $connection->query('... WHERE %ex.[id] = 1', $table->getFqnExpression());
* ```
* @return array<mixed>
*/
public function getFqnExpression(): array
public function __construct(
public readonly Fqn $fqnName,
public readonly bool $isView,
)
{
if ($this->schema === '') {
return ['%table', $this->name];
} else {
return ['%table.%table', $this->schema, $this->name];
}
}
}
48 changes: 23 additions & 25 deletions src/Platforms/MySqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Nextras\Dbal\IConnection;
use Nextras\Dbal\Platforms\Data\Column;
use Nextras\Dbal\Platforms\Data\ForeignKey;
use Nextras\Dbal\Platforms\Data\Fqn;
use Nextras\Dbal\Platforms\Data\Table;
use Nextras\Dbal\Utils\DateTimeHelper;
use Nextras\Dbal\Utils\JsonHelper;
Expand Down Expand Up @@ -58,12 +59,11 @@ public function getTables(?string $schema = null): array

$tables = [];
foreach ($result as $row) {
$table = new Table();
$table->name = (string) $row->TABLE_NAME;
$table->schema = (string) $row->TABLE_SCHEMA;
$table->isView = $row->TABLE_TYPE === 'VIEW';

$tables[$table->getUnescapedFqn()] = $table;
$table = new Table(
fqnName: new Fqn((string) $row->TABLE_NAME, (string) $row->TABLE_SCHEMA),
isView: $row->TABLE_TYPE === 'VIEW',
);
$tables[$table->fqnName->getUnescaped()] = $table;
}
return $tables;
}
Expand All @@ -81,17 +81,17 @@ public function getColumns(string $table, ?string $schema = null): array
foreach ($query as $row) {
$type = explode('(', (string) $row->Type);

$column = new Column();
$column->name = (string) $row->Field;
$column->type = strtoupper($type[0]);
$column->size = isset($type[1]) ? (int) $type[1] : null;
$column->default = $row->Default !== null ? (string) $row->Default : null;
$column->isPrimary = $row->Key === 'PRI';
$column->isAutoincrement = $row->Extra === 'auto_increment';
$column->isUnsigned = (bool) strstr((string) $row->Type, 'unsigned');
$column->isNullable = $row->Null === 'YES';
$column->meta = [];

$column = new Column(
name: (string) $row->Field,
type: strtoupper($type[0]),
size: isset($type[1]) ? (int) $type[1] : null,
default: $row->Default !== null ? (string) $row->Default : null,
isPrimary: $row->Key === 'PRI',
isAutoincrement: $row->Extra === 'auto_increment',
isUnsigned: (bool) strstr((string) $row->Type, 'unsigned'),
isNullable: $row->Null === 'YES',
meta: [],
);
$columns[$column->name] = $column;
}
return $columns;
Expand Down Expand Up @@ -122,14 +122,12 @@ public function getForeignKeys(string $table, ?string $schema = null): array
/** @var array<string, ForeignKey> $keys */
$keys = [];
foreach ($result as $row) {
$foreignKey = new ForeignKey();
$foreignKey->name = (string) $row->CONSTRAINT_NAME;
$foreignKey->schema = (string) $row->CONSTRAINT_SCHEMA;
$foreignKey->column = (string) $row->COLUMN_NAME;
$foreignKey->refTable = (string) $row->REFERENCED_TABLE_NAME;
$foreignKey->refTableSchema = (string) $row->REFERENCED_TABLE_SCHEMA;
$foreignKey->refColumn = (string) $row->REFERENCED_COLUMN_NAME;

$foreignKey = new ForeignKey(
fqnName: new Fqn((string) $row->CONSTRAINT_NAME, (string) $row->CONSTRAINT_SCHEMA),
column: (string) $row->COLUMN_NAME,
refTable: new Fqn((string) $row->REFERENCED_TABLE_NAME, (string) $row->REFERENCED_TABLE_SCHEMA),
refColumn: (string) $row->REFERENCED_COLUMN_NAME,
);
$keys[$foreignKey->column] = $foreignKey;
}
return $keys;
Expand Down
48 changes: 23 additions & 25 deletions src/Platforms/PostgreSqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Nextras\Dbal\IConnection;
use Nextras\Dbal\Platforms\Data\Column;
use Nextras\Dbal\Platforms\Data\ForeignKey;
use Nextras\Dbal\Platforms\Data\Fqn;
use Nextras\Dbal\Platforms\Data\Table;
use Nextras\Dbal\Utils\DateTimeHelper;
use Nextras\Dbal\Utils\JsonHelper;
Expand Down Expand Up @@ -64,12 +65,11 @@ public function getTables(?string $schema = null): array

$tables = [];
foreach ($result as $row) {
$table = new Table();
$table->name = (string) $row->name;
$table->schema = (string) $row->schema;
$table->isView = (bool) $row->is_view;

$tables[$table->getUnescapedFqn()] = $table;
$table = new Table(
fqnName: new Fqn((string) $row->name, (string) $row->schema),
isView: (bool) $row->is_view,
);
$tables[$table->fqnName->getUnescaped()] = $table;
}
return $tables;
}
Expand Down Expand Up @@ -110,17 +110,17 @@ public function getColumns(string $table, ?string $schema = null): array

$columns = [];
foreach ($result as $row) {
$column = new Column();
$column->name = (string) $row->name;
$column->type = (string) $row->type;
$column->size = $row->size !== null ? (int) $row->size : null;
$column->default = $row->default !== null ? (string) $row->default : null;
$column->isPrimary = (bool) $row->is_primary;
$column->isAutoincrement = (bool) $row->is_autoincrement;
$column->isUnsigned = false;
$column->isNullable = (bool) $row->is_nullable;
$column->meta = isset($row->sequence) ? ['sequence' => $row->sequence] : [];

$column = new Column(
name: (string) $row->name,
type: (string) $row->type,
size: $row->size !== null ? (int) $row->size : null,
default: $row->default !== null ? (string) $row->default : null,
isPrimary: (bool) $row->is_primary,
isAutoincrement: (bool) $row->is_autoincrement,
isUnsigned: false,
isNullable: (bool) $row->is_nullable,
meta: isset($row->sequence) ? ['sequence' => $row->sequence] : [],
);
$columns[$column->name] = $column;
}
return $columns;
Expand Down Expand Up @@ -157,14 +157,12 @@ public function getForeignKeys(string $table, ?string $schema = null): array

$keys = [];
foreach ($result as $row) {
$foreignKey = new ForeignKey();
$foreignKey->name = (string) $row->name;
$foreignKey->schema = (string) $row->schema;
$foreignKey->column = (string) $row->column;
$foreignKey->refTable = (string) $row->ref_table;
$foreignKey->refTableSchema = (string) $row->ref_table_schema;
$foreignKey->refColumn = (string) $row->ref_column;

$foreignKey = new ForeignKey(
fqnName: new Fqn((string) $row->name, (string) $row->schema),
column: (string) $row->column,
refTable: new Fqn((string) $row->ref_table, (string) $row->ref_table_schema),
refColumn: (string) $row->ref_column,
);
$keys[$foreignKey->column] = $foreignKey;
}
return $keys;
Expand Down
Loading

0 comments on commit 38c038d

Please sign in to comment.