Skip to content

Commit

Permalink
Merge pull request #41 from dreamfactorysoftware/fix-constraints
Browse files Browse the repository at this point in the history
Override base constraints handling method
  • Loading branch information
Anas authored Jan 30, 2023
2 parents f956ece + ef8a6fe commit af79181
Showing 1 changed file with 150 additions and 0 deletions.
150 changes: 150 additions & 0 deletions src/Services/RedshiftDb.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace DreamFactory\Core\Aws\Services;

use DreamFactory\Core\Database\Schema\RelationSchema;
use DreamFactory\Core\Database\Schema\TableSchema;
use DreamFactory\Core\Enums\DbSimpleTypes;
use DreamFactory\Core\SqlDb\Resources\StoredFunction;
use DreamFactory\Core\SqlDb\Resources\StoredProcedure;
use DreamFactory\Core\SqlDb\Services\SqlDb;
Expand Down Expand Up @@ -36,4 +39,151 @@ public function getResourceHandlers()

return $handlers;
}

protected function updateTableWithConstraints(TableSchema $table, $constraints)
{
$serviceId = $this->getServiceId();
$defaultSchema = $this->getNamingSchema();

// handle local constraints
$ts = strtolower($table->schemaName);
$tn = strtolower($table->resourceName);
if (isset($constraints[$ts][$tn])) {
foreach ($constraints[$ts][$tn] as $conName => $constraint) {
$table->constraints[strtolower($conName)] = $constraint;
$cn = (array)$constraint['column_name'];
$type = strtolower(array_get($constraint, 'constraint_type', ''));
switch ($type[0]) {
case 'p':
foreach ($cn as $cndx => $colName) {
if ($column = $table->getColumn($colName)) {
$column->isPrimaryKey = true;
if ((1 === count($cn)) && $column->autoIncrement &&
(DbSimpleTypes::TYPE_INTEGER === $column->type)) {
$column->type = DbSimpleTypes::TYPE_ID;
}
$table->addColumn($column);
$table->addPrimaryKey($colName);
}
}
break;
case 'u':
foreach ($cn as $cndx => $colName) {
if ($column = $table->getColumn($colName)) {
$column->isUnique = true;
$table->addColumn($column);
}
}
break;
case 'f':
// belongs_to
$rts = array_get($constraint, 'referenced_table_schema', '');
$rtn = array_get($constraint, 'referenced_table_name', '');
$rcn = (array)array_get($constraint, 'referenced_column_name');
$name = ($rts == $defaultSchema) ? $rtn : $rts . '.' . $rtn;
foreach ($cn as $cndx => $colName) {
if ($column = $table->getColumn($colName)) {
$column->isForeignKey = true;
$column->refTable = $name;
$column->refField = array_get($rcn, $cndx);
if ((1 === count($rcn)) && (DbSimpleTypes::TYPE_INTEGER === $column->type)) {
$column->type = DbSimpleTypes::TYPE_REF;
}
$table->addColumn($column);
}
}

// Add it to our foreign references as well
$relation = new RelationSchema([
'type' => RelationSchema::BELONGS_TO,
'field' => $cn,
'ref_service_id' => $serviceId,
'ref_table' => $name,
'ref_field' => $rcn,
'ref_on_update' => array_get($constraint, 'update_rule'),
'ref_on_delete' => array_get($constraint, 'delete_rule'),
]);

$table->addRelation($relation);
break;
}
}
}

foreach ($constraints as $constraintName => $constraint) {
if (0 !== strncasecmp('f', strtolower(array_get($constraint, 'constraint_type', '')), 1)) {
continue;
}

$rts = array_get($constraint, 'referenced_table_schema', '');
$rtn = array_get($constraint, 'referenced_table_name');
if ((0 === strcasecmp($rtn, $table->resourceName)) && (0 === strcasecmp($rts, $table->schemaName))) {
$ts = array_get($constraint, 'table_schema', '');
$tn = array_get($constraint, 'table_name');
$tsk = strtolower($ts);
$tnk = strtolower($tn);
$cn = array_get($constraint, 'column_name');
$rcn = array_get($constraint, 'referenced_column_name');
$name = ($ts == $defaultSchema) ? $tn : $ts . '.' . $tn;
$type = RelationSchema::HAS_MANY;
if (isset($constraints[$tsk][$tnk])) {
foreach ($constraints[$tsk][$tnk] as $constraintName2 => $constraint2) {
$type2 = strtolower(array_get($constraint2, 'constraint_type', ''));
switch ($type2[0]) {
case 'p':
case 'u':
// if this references a primary or unique constraint on the table then it is HAS_ONE
$cn2 = $constraint2['column_name'];
if ($cn2 === $cn) {
$type = RelationSchema::HAS_ONE;
}
break;
case 'f':
// if other has foreign keys to other tables, we can say these are related as well
$rts2 = array_get($constraint2, 'referenced_table_schema', '');
$rtn2 = array_get($constraint2, 'referenced_table_name');
if (!((0 === strcasecmp($rts2, $table->schemaName)) &&
(0 === strcasecmp($rtn2, $table->resourceName)))
) {
$name2 = ($rts2 == $defaultSchema) ? $rtn2 : $rts2 . '.' . $rtn2;
$cn2 = array_get($constraint2, 'column_name');
$rcn2 = array_get($constraint2, 'referenced_column_name');
// not same as parent, i.e. via reference back to self
// not the same key
$relation =
new RelationSchema([
'type' => RelationSchema::MANY_MANY,
'field' => $rcn,
'ref_service_id' => $serviceId,
'ref_table' => $name2,
'ref_field' => $rcn2,
'ref_on_update' => array_get($constraint, 'update_rule'),
'ref_on_delete' => array_get($constraint, 'delete_rule'),
'junction_service_id' => $serviceId,
'junction_table' => $name,
'junction_field' => $cn,
'junction_ref_field' => $cn2
]);

$table->addRelation($relation);
}
break;
}
}

$relation = new RelationSchema([
'type' => $type,
'field' => $rcn,
'ref_service_id' => $serviceId,
'ref_table' => $name,
'ref_field' => $cn,
'ref_on_update' => array_get($constraint, 'update_rule'),
'ref_on_delete' => array_get($constraint, 'delete_rule'),
]);

$table->addRelation($relation);
}
}
}
}
}

0 comments on commit af79181

Please sign in to comment.