prisma-client-php 0.0.38 → 0.0.40
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.
- package/dist/index.enc +1 -1
- package/dist/src/Lib/Prisma/Classes/PPHPUtility.php +259 -123
- package/package.json +1 -1
|
@@ -749,105 +749,273 @@ final class PPHPUtility
|
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
private static function handleImplicitRelationSelect(
|
|
753
|
+
string $model,
|
|
754
|
+
string $relatedModel,
|
|
755
|
+
string $dbType,
|
|
756
|
+
PDO $pdo,
|
|
757
|
+
mixed $primaryId
|
|
758
|
+
): array {
|
|
759
|
+
$implicitModelInfo = PPHPUtility::compareStringsAlphabetically($relatedModel, $model);
|
|
760
|
+
$searchColumn = ($relatedModel === $implicitModelInfo['A']) ? 'B' : 'A';
|
|
761
|
+
$tableName = self::quoteColumnName($dbType, $implicitModelInfo['Name']);
|
|
762
|
+
$searchColumnQuoted = self::quoteColumnName($dbType, $searchColumn);
|
|
763
|
+
|
|
764
|
+
$sqlSelect = "SELECT * FROM $tableName WHERE $searchColumnQuoted = ?";
|
|
765
|
+
$stmtSelect = $pdo->prepare($sqlSelect);
|
|
766
|
+
$stmtSelect->execute([$primaryId]);
|
|
767
|
+
return $stmtSelect->fetchAll();
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
private static function handleImplicitRelationInsert(
|
|
771
|
+
string $model,
|
|
772
|
+
string $relatedModel,
|
|
773
|
+
string $dbType,
|
|
774
|
+
PDO $pdo,
|
|
775
|
+
mixed $primaryId,
|
|
776
|
+
mixed $relatedId
|
|
777
|
+
): array {
|
|
778
|
+
$implicitModelInfo = PPHPUtility::compareStringsAlphabetically($relatedModel, $model);
|
|
779
|
+
$searchColumn = ($relatedModel === $implicitModelInfo['A']) ? 'B' : 'A';
|
|
780
|
+
$returnColumn = ($searchColumn === 'A') ? 'B' : 'A';
|
|
781
|
+
|
|
782
|
+
if ($implicitModelInfo['A'] === $model) {
|
|
783
|
+
$searchColumnValue = $primaryId;
|
|
784
|
+
$returnColumnValue = $relatedId;
|
|
785
|
+
} else {
|
|
786
|
+
$searchColumnValue = $relatedId;
|
|
787
|
+
$returnColumnValue = $primaryId;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
$tableName = self::quoteColumnName($dbType, $implicitModelInfo['Name']);
|
|
791
|
+
$searchColumnQuoted = self::quoteColumnName($dbType, $searchColumn);
|
|
792
|
+
$returnColumnQuoted = self::quoteColumnName($dbType, $returnColumn);
|
|
793
|
+
|
|
794
|
+
$sql = "INSERT IGNORE INTO $tableName ($searchColumnQuoted, $returnColumnQuoted) VALUES (?, ?)";
|
|
795
|
+
$stmt = $pdo->prepare($sql);
|
|
796
|
+
$stmt->execute([$searchColumnValue, $returnColumnValue]);
|
|
797
|
+
|
|
798
|
+
$sqlSelect = "SELECT * FROM $tableName WHERE $searchColumnQuoted = ? AND $returnColumnQuoted = ?";
|
|
799
|
+
$stmtSelect = $pdo->prepare($sqlSelect);
|
|
800
|
+
$stmtSelect->execute([$searchColumnValue, $returnColumnValue]);
|
|
801
|
+
|
|
802
|
+
$result = $stmtSelect->fetch();
|
|
803
|
+
return $result ?: [];
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
private static function handleImplicitRelationDelete(
|
|
807
|
+
string $model,
|
|
808
|
+
string $relatedModel,
|
|
809
|
+
string $dbType,
|
|
810
|
+
PDO $pdo,
|
|
811
|
+
mixed $primaryId,
|
|
812
|
+
array $allNewRelatedIds
|
|
813
|
+
): void {
|
|
814
|
+
$implicitModelInfo = PPHPUtility::compareStringsAlphabetically($relatedModel, $model);
|
|
815
|
+
$searchColumn = ($relatedModel === $implicitModelInfo['A']) ? 'B' : 'A';
|
|
816
|
+
$returnColumn = ($searchColumn === 'A') ? 'B' : 'A';
|
|
817
|
+
|
|
818
|
+
$tableName = self::quoteColumnName($dbType, $implicitModelInfo['Name']);
|
|
819
|
+
$searchColumnQuoted = self::quoteColumnName($dbType, $searchColumn);
|
|
820
|
+
$returnColumnQuoted = self::quoteColumnName($dbType, $returnColumn);
|
|
821
|
+
|
|
822
|
+
if (count($allNewRelatedIds) > 0) {
|
|
823
|
+
$placeholders = implode(',', array_fill(0, count($allNewRelatedIds), '?'));
|
|
824
|
+
$sqlDelete = "DELETE FROM $tableName WHERE $searchColumnQuoted = ? AND $returnColumnQuoted NOT IN ($placeholders)";
|
|
825
|
+
$stmtDelete = $pdo->prepare($sqlDelete);
|
|
826
|
+
$stmtDelete->execute(array_merge([$primaryId], $allNewRelatedIds));
|
|
827
|
+
} else {
|
|
828
|
+
$sqlDelete = "DELETE FROM $tableName WHERE $searchColumnQuoted = ?";
|
|
829
|
+
$stmtDelete = $pdo->prepare($sqlDelete);
|
|
830
|
+
$stmtDelete->execute([$primaryId]);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
752
834
|
public static function processRelation(
|
|
753
|
-
|
|
835
|
+
string $modelName,
|
|
836
|
+
string $relatedFieldName,
|
|
754
837
|
array $fieldData,
|
|
755
|
-
array $relationFromFields,
|
|
756
|
-
array $relationToFields,
|
|
757
|
-
string $relatedClassName,
|
|
758
|
-
string $model,
|
|
759
838
|
PDO $pdo,
|
|
760
839
|
string $dbType,
|
|
761
|
-
string $lastInsertId = '',
|
|
762
840
|
bool $requestOption = true,
|
|
763
841
|
): array {
|
|
764
|
-
$fieldName = $relatedField['name'];
|
|
765
|
-
if (count($relationFromFields) !== count($relationToFields)) {
|
|
766
|
-
throw new Exception("Mismatch between 'relationFromFields' and 'relationToFields' for relation '$fieldName'.");
|
|
767
|
-
}
|
|
768
842
|
|
|
769
|
-
$
|
|
770
|
-
$
|
|
843
|
+
$modelClassName = "Lib\\Prisma\\Classes\\" . $modelName;
|
|
844
|
+
$modelReflection = new ReflectionClass($modelClassName);
|
|
845
|
+
$modelClass = $modelReflection->newInstance($pdo);
|
|
846
|
+
$modelFieldsRelatedWithKeys = $modelClass->_fieldsRelatedWithKeys[$relatedFieldName];
|
|
847
|
+
$modelRelatedFromFields = $modelFieldsRelatedWithKeys['relationFromFields'];
|
|
848
|
+
$modelRelatedToFields = $modelFieldsRelatedWithKeys['relationToFields'];
|
|
849
|
+
$modelRelatedField = $modelClass->_fields[$relatedFieldName];
|
|
850
|
+
$modelRelatedFieldIsList = $modelRelatedField['isList'] ?? false;
|
|
851
|
+
$modelRelatedFieldType = $modelRelatedField['type'];
|
|
852
|
+
$relatedClassName = "Lib\\Prisma\\Classes\\" . $modelRelatedFieldType;
|
|
853
|
+
$relatedReflection = new ReflectionClass($relatedClassName);
|
|
854
|
+
$relatedClass = $relatedReflection->newInstance($pdo);
|
|
855
|
+
|
|
771
856
|
$relatedResult = null;
|
|
857
|
+
foreach ($fieldData as $action => $actionData) {
|
|
858
|
+
$operations = isset($actionData[0]) ? $actionData : [$actionData];
|
|
859
|
+
|
|
860
|
+
foreach ($operations as $op) {
|
|
861
|
+
switch ($action) {
|
|
862
|
+
case 'connect':
|
|
863
|
+
if (empty($modelRelatedFromFields) && empty($modelRelatedToFields)) {
|
|
864
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
865
|
+
$modelFieldData = $op[$modelName];
|
|
866
|
+
$relatedResult = self::handleImplicitRelationInsert(
|
|
867
|
+
$modelName,
|
|
868
|
+
$modelRelatedFieldType,
|
|
869
|
+
$dbType,
|
|
870
|
+
$pdo,
|
|
871
|
+
$relatedFieldData[$relatedClass->_primaryKey],
|
|
872
|
+
$modelFieldData[$modelClass->_primaryKey]
|
|
873
|
+
);
|
|
874
|
+
} else {
|
|
875
|
+
if (!$modelRelatedFieldIsList && count($operations) > 1) {
|
|
876
|
+
throw new Exception("Cannot connect multiple records for a non-list relation '$relatedFieldName'.");
|
|
877
|
+
}
|
|
772
878
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
$searchColumnValue = $lastInsertId;
|
|
788
|
-
$returnColumnValue = $relatedId;
|
|
789
|
-
} else {
|
|
790
|
-
$searchColumnValue = $relatedId;
|
|
791
|
-
$returnColumnValue = $lastInsertId;
|
|
792
|
-
}
|
|
879
|
+
$relatedResult = $relatedClass->findUnique(['where' => $op]);
|
|
880
|
+
}
|
|
881
|
+
break;
|
|
882
|
+
case 'connectOrCreate':
|
|
883
|
+
if (empty($modelRelatedFromFields) && empty($modelRelatedToFields)) {
|
|
884
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
885
|
+
$modelFieldData = $op[$modelName];
|
|
886
|
+
$existingRecord = $relatedClass->findFirst(['where' => $relatedFieldData['where']]);
|
|
887
|
+
|
|
888
|
+
if ($existingRecord) {
|
|
889
|
+
$record = $existingRecord;
|
|
890
|
+
} else {
|
|
891
|
+
$record = $relatedClass->create(['data' => $relatedFieldData['create']]);
|
|
892
|
+
}
|
|
793
893
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
$stmtSelect->execute([$searchColumnValue, $returnColumnValue]);
|
|
804
|
-
$relatedResult = $stmtSelect->fetch();
|
|
805
|
-
} else {
|
|
806
|
-
$relatedData = ['where' => $fieldData['connect']];
|
|
807
|
-
$relatedResult = $relatedClass->findUnique($relatedData);
|
|
808
|
-
}
|
|
809
|
-
} elseif (isset($fieldData['connectOrCreate'])) {
|
|
810
|
-
$relatedData = ['where' => $fieldData['connectOrCreate']['where']];
|
|
811
|
-
$relatedResult = $relatedClass->findUnique($relatedData);
|
|
894
|
+
$relatedResult = self::handleImplicitRelationInsert(
|
|
895
|
+
$modelName,
|
|
896
|
+
$modelRelatedFieldType,
|
|
897
|
+
$dbType,
|
|
898
|
+
$pdo,
|
|
899
|
+
$record->{$relatedClass->_primaryKey},
|
|
900
|
+
$modelFieldData[$modelClass->_primaryKey]
|
|
901
|
+
);
|
|
902
|
+
} else {
|
|
812
903
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
904
|
+
if (!$modelRelatedFieldIsList && count($operations) > 1) {
|
|
905
|
+
throw new Exception("Cannot connectOrCreate multiple records for a non-list relation '$relatedFieldName'.");
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
$existing = $relatedClass->findUnique(['where' => $op]);
|
|
909
|
+
|
|
910
|
+
if ($existing) {
|
|
911
|
+
$relatedResult = $existing;
|
|
912
|
+
} else {
|
|
913
|
+
$relatedResult = $relatedClass->create(['data' => $op]);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
break;
|
|
917
|
+
case 'create':
|
|
918
|
+
if (empty($modelRelatedFromFields) && empty($modelRelatedToFields)) {
|
|
919
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
920
|
+
$modelFieldData = $op[$modelName];
|
|
921
|
+
$relatedCreatedData = $relatedClass->create(['data' => $relatedFieldData]);
|
|
922
|
+
$relatedResult = self::handleImplicitRelationInsert(
|
|
923
|
+
$modelName,
|
|
924
|
+
$modelRelatedFieldType,
|
|
925
|
+
$dbType,
|
|
926
|
+
$pdo,
|
|
927
|
+
$relatedCreatedData->{$relatedClass->_primaryKey},
|
|
928
|
+
$modelFieldData[$modelClass->_primaryKey]
|
|
929
|
+
);
|
|
930
|
+
} else {
|
|
931
|
+
if (!$modelRelatedFieldIsList && count($operations) > 1) {
|
|
932
|
+
throw new Exception("Cannot create multiple records for a non-list relation '$relatedFieldName'.");
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
$relatedResult = $relatedClass->create(['data' => $op]);
|
|
936
|
+
}
|
|
937
|
+
break;
|
|
938
|
+
case 'delete':
|
|
939
|
+
$whereCondition = $op[$modelRelatedFieldType];
|
|
940
|
+
$relatedResult = $relatedClass->delete(['where' => $whereCondition]);
|
|
941
|
+
break;
|
|
942
|
+
case 'disconnect':
|
|
943
|
+
if (empty($modelRelatedFromFields) && empty($modelRelatedToFields)) {
|
|
944
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
945
|
+
$modelFieldData = $op[$modelName];
|
|
946
|
+
$relatedResult = self::handleImplicitRelationDelete(
|
|
947
|
+
$modelName,
|
|
948
|
+
$modelRelatedFieldType,
|
|
949
|
+
$dbType,
|
|
950
|
+
$pdo,
|
|
951
|
+
$modelFieldData[$modelClass->_primaryKey],
|
|
952
|
+
$relatedFieldData[$relatedClass->_primaryKey]
|
|
953
|
+
);
|
|
954
|
+
} else {
|
|
955
|
+
$relatedResult = $relatedClass->delete(['where' => $op]);
|
|
956
|
+
}
|
|
957
|
+
break;
|
|
958
|
+
case 'set':
|
|
959
|
+
if (empty($modelRelatedFromFields) && empty($modelRelatedToFields)) {
|
|
960
|
+
$newRelatedIds = [];
|
|
961
|
+
$primaryId = null;
|
|
962
|
+
foreach ($operations as $opSet) {
|
|
963
|
+
$relatedFieldData = $opSet[$modelRelatedFieldType];
|
|
964
|
+
$modelFieldData = $opSet[$modelName];
|
|
965
|
+
$newRelatedIds[] = $relatedFieldData[$relatedClass->_primaryKey];
|
|
966
|
+
if (!$primaryId) {
|
|
967
|
+
$primaryId = $modelFieldData[$modelClass->_primaryKey];
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
$newRelatedIds = array_unique($newRelatedIds);
|
|
971
|
+
|
|
972
|
+
self::handleImplicitRelationDelete(
|
|
973
|
+
$modelName,
|
|
974
|
+
$modelRelatedFieldType,
|
|
975
|
+
$dbType,
|
|
976
|
+
$pdo,
|
|
977
|
+
$primaryId,
|
|
978
|
+
$newRelatedIds
|
|
979
|
+
);
|
|
980
|
+
|
|
981
|
+
foreach ($newRelatedIds as $relatedId) {
|
|
982
|
+
self::handleImplicitRelationInsert(
|
|
983
|
+
$modelName,
|
|
984
|
+
$modelRelatedFieldType,
|
|
985
|
+
$dbType,
|
|
986
|
+
$pdo,
|
|
987
|
+
$relatedId,
|
|
988
|
+
$primaryId
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
$relatedResult = self::handleImplicitRelationSelect(
|
|
993
|
+
$modelName,
|
|
994
|
+
$modelRelatedFieldType,
|
|
995
|
+
$dbType,
|
|
996
|
+
$pdo,
|
|
997
|
+
$primaryId
|
|
998
|
+
);
|
|
999
|
+
} else {
|
|
1000
|
+
$relatedResult = $relatedClass->findUnique(['where' => $op]);
|
|
1001
|
+
}
|
|
1002
|
+
break;
|
|
1003
|
+
case 'update':
|
|
1004
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
1005
|
+
$relatedResult = $relatedClass->update(['where' => $relatedFieldData['where'], 'data' => $relatedFieldData['data']]);
|
|
1006
|
+
break;
|
|
1007
|
+
case 'upsert':
|
|
1008
|
+
$relatedFieldData = $op[$modelRelatedFieldType];
|
|
1009
|
+
$existing = $relatedClass->findUnique(['where' => $relatedFieldData['where']]);
|
|
1010
|
+
|
|
1011
|
+
if ($existing) {
|
|
1012
|
+
$relatedResult = $relatedClass->update(['where' => $relatedFieldData['where'], 'data' => $relatedFieldData['data']]);
|
|
1013
|
+
} else {
|
|
1014
|
+
$relatedResult = $relatedClass->create(['data' => $op]);
|
|
1015
|
+
}
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
848
1018
|
}
|
|
849
|
-
} else {
|
|
850
|
-
throw new Exception("No valid action provided for relation '$fieldName'.");
|
|
851
1019
|
}
|
|
852
1020
|
|
|
853
1021
|
$relatedResult = (array) $relatedResult;
|
|
@@ -857,14 +1025,14 @@ final class PPHPUtility
|
|
|
857
1025
|
}
|
|
858
1026
|
|
|
859
1027
|
if (!$relatedResult) {
|
|
860
|
-
throw new Exception("Failed to process related record for '$
|
|
1028
|
+
throw new Exception("Failed to process related record for '$relatedFieldName'.");
|
|
861
1029
|
}
|
|
862
1030
|
|
|
863
1031
|
$bindings = [];
|
|
864
|
-
foreach ($
|
|
865
|
-
$toField = $
|
|
1032
|
+
foreach ($modelRelatedFromFields as $index => $fromField) {
|
|
1033
|
+
$toField = $modelRelatedToFields[$index];
|
|
866
1034
|
if (!isset($relatedResult[$toField])) {
|
|
867
|
-
throw new Exception("The field '$toField' is missing in the related data for '$
|
|
1035
|
+
throw new Exception("The field '$toField' is missing in the related data for '$relatedFieldName'.");
|
|
868
1036
|
}
|
|
869
1037
|
|
|
870
1038
|
$bindings[$fromField] = $relatedResult[$toField];
|
|
@@ -873,38 +1041,6 @@ final class PPHPUtility
|
|
|
873
1041
|
return $bindings;
|
|
874
1042
|
}
|
|
875
1043
|
|
|
876
|
-
public static function mergeForeignKeysIfNeeded(
|
|
877
|
-
array $item,
|
|
878
|
-
string $action,
|
|
879
|
-
array $relationToFields,
|
|
880
|
-
array $relationFromFields,
|
|
881
|
-
$lastInsertId,
|
|
882
|
-
array $fields
|
|
883
|
-
): array {
|
|
884
|
-
foreach ($relationToFields as $idx => $toField) {
|
|
885
|
-
if (!array_key_exists($toField, $fields)) {
|
|
886
|
-
continue;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
$fromField = $relationFromFields[$idx] ?? null;
|
|
890
|
-
if (!$fromField) {
|
|
891
|
-
continue;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
if ($action === 'create') {
|
|
895
|
-
$item[$fromField] = $lastInsertId;
|
|
896
|
-
} elseif ($action === 'connect') {
|
|
897
|
-
$item[$fromField] = $lastInsertId;
|
|
898
|
-
} elseif ($action === 'connectOrCreate') {
|
|
899
|
-
if (isset($item['where'])) {
|
|
900
|
-
$item['where'][$fromField] = $lastInsertId;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
return $item;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
1044
|
public static function populateIncludedRelations(
|
|
909
1045
|
array $records,
|
|
910
1046
|
array $includes,
|
package/package.json
CHANGED