@smartive/graphql-magic 23.13.0 → 23.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,6 @@ import {
20
20
  validateCheckConstraint,
21
21
  validateExcludeConstraint,
22
22
  } from '../models/utils';
23
- import { getColumnName } from '../resolvers';
24
23
  import { Value } from '../values';
25
24
  import { ParsedFunction } from './types';
26
25
  import {
@@ -676,26 +675,30 @@ export class MigrationGenerator {
676
675
 
677
676
  if (isUpdatableModel(model)) {
678
677
  const updatableFields = fields.filter(and(isUpdatableField, isStoredInDatabase));
679
- if (!updatableFields.length) {
678
+ const revisionFieldsNeedingAlter = updatableFields.filter((field) => this.revisionFieldNeedsSchemaAlter(model, field));
679
+ if (!revisionFieldsNeedingAlter.length) {
680
680
  return;
681
681
  }
682
682
 
683
683
  up.push(() => {
684
684
  this.alterTable(`${model.name}Revision`, () => {
685
- for (const [index, field] of updatableFields.entries()) {
686
- this.columnRaw(field, { alter: true }, index);
685
+ for (const [index, field] of revisionFieldsNeedingAlter.entries()) {
686
+ this.columnRaw(field, { alter: true, setNonNull: false }, index);
687
687
  }
688
688
  });
689
689
  });
690
690
 
691
691
  down.push(() => {
692
692
  this.alterTable(`${model.name}Revision`, () => {
693
- for (const [index, field] of updatableFields.entries()) {
693
+ for (const [index, field] of revisionFieldsNeedingAlter.entries()) {
694
694
  this.columnRaw(
695
695
  field,
696
- { alter: true },
696
+ { alter: true, setNonNull: false },
697
697
  index,
698
- summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name),
698
+ summonByName(
699
+ this.columns[`${model.name}Revision`],
700
+ field.kind === 'relation' ? `${field.name}Id` : field.name,
701
+ ),
699
702
  );
700
703
  }
701
704
  });
@@ -730,25 +733,29 @@ export class MigrationGenerator {
730
733
 
731
734
  if (isUpdatableModel(model)) {
732
735
  const updatableFields = fields.filter(and(isUpdatableField, isStoredInDatabase));
733
- if (!updatableFields.length) {
736
+ const revisionFieldsNeedingAlter = updatableFields.filter((field) => this.revisionFieldNeedsSchemaAlter(model, field));
737
+ if (!revisionFieldsNeedingAlter.length) {
734
738
  return;
735
739
  }
736
740
 
737
741
  up.push(() => {
738
742
  this.alterTable(`${model.name}Revision`, () => {
739
- for (const field of updatableFields) {
740
- this.column(field, { alter: true });
743
+ for (const field of revisionFieldsNeedingAlter) {
744
+ this.column(field, { alter: true, setUnique: false, setNonNull: false, foreign: false });
741
745
  }
742
746
  });
743
747
  });
744
748
 
745
749
  down.push(() => {
746
750
  this.alterTable(`${model.name}Revision`, () => {
747
- for (const field of updatableFields) {
751
+ for (const field of revisionFieldsNeedingAlter) {
748
752
  this.column(
749
753
  field,
750
- { alter: true },
751
- summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name),
754
+ { alter: true, setUnique: false, setNonNull: false, foreign: false },
755
+ summonByName(
756
+ this.columns[`${model.name}Revision`],
757
+ field.kind === 'relation' ? `${field.name}Id` : field.name,
758
+ ),
752
759
  );
753
760
  }
754
761
  });
@@ -774,7 +781,7 @@ export class MigrationGenerator {
774
781
  }
775
782
 
776
783
  for (const field of model.fields.filter(and(isUpdatableField, not(isInherited), isStoredInDatabase))) {
777
- this.column(field, { setUnique: false, setDefault: false });
784
+ this.column(field, { setUnique: false, setDefault: false, setNonNull: false, foreign: false });
778
785
  }
779
786
  });
780
787
  }
@@ -786,45 +793,9 @@ export class MigrationGenerator {
786
793
  // Create missing revision columns
787
794
  this.alterTable(revisionTable, () => {
788
795
  for (const field of missingRevisionFields) {
789
- this.column(field, { setUnique: false, setNonNull: false, setDefault: false });
796
+ this.column(field, { setUnique: false, setNonNull: false, setDefault: false, foreign: false });
790
797
  }
791
798
  });
792
-
793
- // Insert data for missing revisions columns
794
- const revisionFieldsWithDataToCopy = missingRevisionFields.filter(
795
- (field) =>
796
- this.columns[model.name].find((col) => col.name === getColumnName(field)) ||
797
- field.defaultValue !== undefined ||
798
- field.nonNull,
799
- );
800
- if (revisionFieldsWithDataToCopy.length) {
801
- this.writer
802
- .write(`await knex('${model.name}Revision').update(`)
803
- .inlineBlock(() => {
804
- for (const { name, kind: type } of revisionFieldsWithDataToCopy) {
805
- const col = type === 'relation' ? `${name}Id` : name;
806
- this.writer
807
- .write(
808
- `${col}: knex.raw('(select "${col}" from "${model.name}" where "${model.name}".id = "${
809
- model.name
810
- }Revision"."${typeToField(model.name)}Id")'),`,
811
- )
812
- .newLine();
813
- }
814
- })
815
- .write(');')
816
- .newLine()
817
- .blankLine();
818
- }
819
-
820
- const nonNullableMissingRevisionFields = missingRevisionFields.filter(({ nonNull }) => nonNull);
821
- if (nonNullableMissingRevisionFields.length) {
822
- this.alterTable(revisionTable, () => {
823
- for (const field of nonNullableMissingRevisionFields) {
824
- this.column(field, { setUnique: false, setDefault: false, alter: true });
825
- }
826
- });
827
- }
828
799
  });
829
800
 
830
801
  down.push(() => {
@@ -1616,24 +1587,32 @@ export class MigrationGenerator {
1616
1587
  }
1617
1588
 
1618
1589
  private hasChanged(model: EntityModel, field: EntityField) {
1590
+ return this.hasChangedOnTable(model.name, field, { respectNullability: true });
1591
+ }
1592
+
1593
+ private hasChangedOnTable(tableName: string, field: EntityField, { respectNullability }: { respectNullability: boolean }) {
1619
1594
  if (field.generateAs?.type === 'expression') {
1620
1595
  return false;
1621
1596
  }
1622
1597
 
1623
- const col = this.getColumn(model.name, field.kind === 'relation' ? `${field.name}Id` : field.name);
1598
+ const col = this.getColumn(tableName, field.kind === 'relation' ? `${field.name}Id` : field.name);
1624
1599
  if (!col) {
1625
1600
  return false;
1626
1601
  }
1627
1602
 
1628
1603
  if (field.generateAs) {
1629
1604
  if (col.generation_expression !== field.generateAs.expression) {
1630
- throw new Error(
1631
- `Column ${col.name} has specific type ${col.generation_expression} but expected ${field.generateAs.expression}`,
1632
- );
1605
+ if (respectNullability) {
1606
+ throw new Error(
1607
+ `Column ${col.name} has specific type ${col.generation_expression} but expected ${field.generateAs.expression}`,
1608
+ );
1609
+ }
1610
+
1611
+ return true;
1633
1612
  }
1634
1613
  }
1635
1614
 
1636
- if ((!field.nonNull && !col.is_nullable) || (field.nonNull && col.is_nullable)) {
1615
+ if (respectNullability && ((!field.nonNull && !col.is_nullable) || (field.nonNull && col.is_nullable))) {
1637
1616
  return true;
1638
1617
  }
1639
1618
 
@@ -1679,6 +1658,27 @@ export class MigrationGenerator {
1679
1658
  return false;
1680
1659
  }
1681
1660
 
1661
+ private revisionFieldNeedsSchemaAlter(model: EntityModel, field: EntityField) {
1662
+ if (field.generateAs?.type === 'expression') {
1663
+ return false;
1664
+ }
1665
+
1666
+ const tableName = `${model.name}Revision`;
1667
+ const colName = field.kind === 'relation' ? `${field.name}Id` : field.name;
1668
+ const revCol = this.getColumn(tableName, colName);
1669
+ if (!revCol) {
1670
+ return false;
1671
+ }
1672
+
1673
+ if (field.generateAs) {
1674
+ if (revCol.generation_expression !== field.generateAs.expression) {
1675
+ return true;
1676
+ }
1677
+ }
1678
+
1679
+ return this.hasChangedOnTable(tableName, field, { respectNullability: false });
1680
+ }
1681
+
1682
1682
  private async handleFunctions(up: Callbacks, down: Callbacks) {
1683
1683
  if (!this.parsedFunctions || this.parsedFunctions.length === 0) {
1684
1684
  return;