protected function InsertRowsIndividually(IConnection $Connection, Table $Table, array $Rows, callable $PostIndividualInsertCallback) { $TableName = $Table->GetName(); $Columns = $Table->GetColumns(); $ColumnNames = array_keys($Columns); $QueryBuilder = $Connection->QueryBuilder(); $this->AppendInsert($QueryBuilder, $TableName, $ColumnNames); $QueryBuilder->Append('('); foreach ($QueryBuilder->Delimit($Columns, ',') as $Column) { $QueryBuilder->AppendColumnData($Column, null); } $QueryBuilder->Append(')'); $PreparedInsert = $QueryBuilder->Build(); $Bindings = $PreparedInsert->GetBindings(); $ColumnValues = array_values($Columns); $ParameterTypes = $this->GetParamterTypes($ColumnValues); foreach ($Rows as $Row) { foreach ($ColumnValues as $Count => $Column) { $Value = $Row[$Column]; $Bindings->Bind($Value, $Value === null ? ParameterType::Null : $ParameterTypes[$Count], $Count); } $PreparedInsert->Execute(); $PostIndividualInsertCallback($Row); } }
public final function PersistRows(IConnection $Connection, Table $Table, array $RowsToPersist) { $KeyedRows = []; $UnkeyedRows = []; array_walk($RowsToPersist, function (Relational\Row $Row) use(&$KeyedRows, &$UnkeyedRows) { if ($Row->HasPrimaryKey()) { $KeyedRows[] =& $Row; } else { $UnkeyedRows[] =& $Row; } }); $HasKeyGenerator = $Table->HasKeyGenerator(); $KeyGeneratorType = null; $ReturningDataKeyGenerator = null; $PostIndividualInsertKeyGenerator = null; if ($HasKeyGenerator) { $KeyGenerator = $Table->GetKeyGenerator(); $KeyGeneratorType = $KeyGenerator->GetKeyGeneratorType(); if (count($UnkeyedRows) === 0) { $KeyGeneratorType = null; } else { if ($KeyGeneratorType === PrimaryKeys\KeyGeneratorType::PreInsert) { /* @var $KeyGenerator PrimaryKeys\PreInsertKeyGenerator */ $KeyGenerator->FillPrimaryKeys($Connection, $UnkeyedRows); } else { if ($KeyGeneratorType === PrimaryKeys\KeyGeneratorType::ReturningData) { /* @var $KeyGenerator PrimaryKeys\ReturningDataKeyGenerator */ $ReturningDataKeyGenerator = $KeyGenerator; } else { if ($KeyGeneratorType === PrimaryKeys\KeyGeneratorType::PostIndividualInsert) { /* @var $KeyGenerator PrimaryKeys\PostIndividualInsertKeyGenerator */ $PostIndividualInsertKeyGenerator = $KeyGenerator; } } } } } if ($this->BatchSize === null || $this->BatchSize >= count($RowsToPersist)) { $this->SaveRows($Connection, $Table, $UnkeyedRows, $KeyedRows, $ReturningDataKeyGenerator, $PostIndividualInsertKeyGenerator); if ($KeyGeneratorType === PrimaryKeys\KeyGeneratorType::PostMultiInsert) { /* @var $KeyGenerator PrimaryKeys\PostMultiInsertKeyGenerator */ $KeyGenerator->FillPrimaryKeys($Connection, $UnkeyedRows); } } else { foreach (array_chunk($RowsToPersist, $this->BatchSize, true) as $RowBatch) { $BatchedKeyedRows = array_intersect_key($RowBatch, $UnkeyedRows); $this->SaveRows($Connection, $Table, $BatchedKeyedRows, array_intersect_key($RowBatch, $KeyedRows), $ReturningDataKeyGenerator, $PostIndividualInsertKeyGenerator); if ($KeyGeneratorType === PrimaryKeys\KeyGeneratorType::PostMultiInsert) { /* @var $KeyGenerator PrimaryKeys\PostMultiInsertKeyGenerator */ $KeyGenerator->FillPrimaryKeys($Connection, $BatchedKeyedRows); } } } }
protected function DeletePrimaryKeysQuery(QueryBuilder $QueryBuilder, Table $Table, array $PrimaryKeys) { $TableName = $Table->GetName(); $DerivedTableName = $TableName . 'PrimaryKeys'; $TransformedDerivedTableName = $TableName . 'PersistencePrimaryKeys'; $PrimaryKeysColumns = $Table->GetPrimaryKeyColumns(); $PrimaryKeyNames = array_keys($PrimaryKeysColumns); $QueryBuilder->AppendIdentifier('DELETE # FROM # INNER JOIN (', [$TableName]); $this->StandardPersister->AppendDataAsInlineTable($QueryBuilder, $PrimaryKeysColumns, $DerivedTableName, $PrimaryKeys); $QueryBuilder->AppendIdentifier(') #', [$TransformedDerivedTableName]); $QueryBuilder->Append(' ON '); foreach ($QueryBuilder->Delimit($PrimaryKeyNames, ' AND ') as $PrimaryKeyName) { $QueryBuilder->AppendIdentifier('# = ', [$TableName, $PrimaryKeyName]); $QueryBuilder->AppendIdentifier('#', [$TransformedDerivedTableName, $PrimaryKeyName]); } }
protected function UpsertRowsQuery(QueryBuilder $QueryBuilder, Table $Table, array $Rows, $ShouldReturnKeyData) { if ($ShouldReturnKeyData) { throw new \Storm\Drivers\Base\Relational\PlatformException('SQLite does not support returning data'); } $Columns = $Table->GetColumns(); $PrimaryKeyColumns = $Table->GetPrimaryKeyColumns(); $ColumnNames = array_keys($Columns); $PrimaryKeyColumnNames = array_keys($PrimaryKeyColumns); $TableName = $Table->GetName(); $DerivedTableName = $TableName . 'Values'; $PrimaryKeyIdentifiers = []; foreach ($PrimaryKeyColumnNames as $ColumnName) { $PrimaryKeyIdentifiers[] = [$TableName, $ColumnName]; } $QueryBuilder->AppendIdentifier('INSERT OR REPLACE INTO #', [$TableName]); $QueryBuilder->AppendIdentifiers('(#)', $ColumnNames, ','); //TODO: Fix unique constraint conflicts $this->AppendDataAsInlineTable($QueryBuilder, $Table->GetColumns(), $DerivedTableName, $Rows); }
public function __construct($Name, IKeyGenerator $KeyGenerator = null, array $Columns, array $StructuralTraits = [], array $RelationalTraits = [], array $ToOneRelations = [], array $ToManyRelations = []) { $this->Name = $Name; $this->_Columns = $Columns; $this->KeyGenerator = $KeyGenerator; $this->StructuralTraits = $StructuralTraits; $this->RelationalTraits = $RelationalTraits; $this->ToOneRelations = $ToOneRelations; $this->ToManyRelations = $ToManyRelations; $this->InitializeStructure(new Database(new \Storm\Drivers\Platforms\Null\NullPlatform(), [])); parent::__construct(); }
protected function UpsertRowsQuery(QueryBuilder $QueryBuilder, Table $Table, array $Rows, $ShouldReturnKeyData) { if ($ShouldReturnKeyData) { throw new \Storm\Drivers\Base\Relational\PlatformException('Mysql does not support returning data'); } $Columns = $Table->GetColumns(); $PrimaryKeyColumns = $Table->GetPrimaryKeyColumns(); $ColumnNames = array_keys($Columns); $PrimaryKeyColumnNames = array_keys($PrimaryKeyColumns); $TableName = $Table->GetName(); $DerivedTableName = $TableName . 'Values'; $PrimaryKeyIdentifiers = []; foreach ($PrimaryKeyColumnNames as $ColumnName) { $PrimaryKeyIdentifiers[] = [$TableName, $ColumnName]; } $QueryBuilder->AppendIdentifier('INSERT INTO #', [$TableName]); $QueryBuilder->AppendIdentifiers('(#)', $ColumnNames, ','); /* * MySQL cannot prepare a statment with an inline table with only a * single row. Bug reported. */ if (count($Rows) === 1) { $this->AppendDataAsInlineRow($QueryBuilder, $Table->GetColumns(), reset($Rows)); } else { $this->AppendDataAsInlineTable($QueryBuilder, $Table->GetColumns(), $DerivedTableName, $Rows); } $this->AppendOnDuplicateKeyUpdate($QueryBuilder, $TableName, $Columns, $PrimaryKeyIdentifiers); }
protected final function OnInitializeRelations(CoreDatabase $Context) { $this->CreateRelations($Context); parent::OnInitializeRelations($Context); }
private function GetTableStructuralTraits(Relational\Table $Table, Relational\Table $CurrentTable) { $Traits = $Table->GetStructuralTraits(); $CurrentTraits = $CurrentTable->GetStructuralTraits(); $TraitsToAdd = []; foreach ($Traits as $Trait) { if (count(array_filter($CurrentTraits, [$Trait, 'Is'])) === 0) { $TraitsToAdd[] = $Trait; } } $TraitsToRemove = []; foreach ($CurrentTraits as $CurrentTrait) { if (count(array_filter($Traits, [$CurrentTrait, 'Is'])) === 0) { $TraitsToRemove[] = $CurrentTrait; } } return [$TraitsToAdd, $TraitsToRemove]; }
public function __construct($Name) { $this->Name = $Name; parent::__construct(); }
public static function AppendAlterTable(QueryBuilder $Builder, Relational\Table $Table) { $Builder->AppendIdentifier('ALTER TABLE # ', [$Table->GetName()]); }
public function __construct() { parent::__construct(); }
protected function AppendDropTableQuery(QueryBuilder $QueryBuilder, Table $Table) { $QueryBuilder->AppendIdentifier('DROP TABLE #', [$Table->GetName()]); }