prisma-client-php 2.0.11 → 2.1.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.
- package/dist/generate.js +2 -1
- package/dist/index.enc +1 -1
- package/dist/init.js +3 -1
- package/dist/src/Lib/Prisma/Classes/PPHPUtility.php +143 -82
- package/package.json +1 -1
- package/dist/src/Lib/Validator.php +0 -738
package/dist/init.js
CHANGED
|
@@ -163,7 +163,8 @@ async function installComposerDependencies(isPrismaPHP) {
|
|
|
163
163
|
composerDependencies.push(
|
|
164
164
|
composerPkg("ezyang/htmlpurifier"),
|
|
165
165
|
composerPkg("symfony/uid"),
|
|
166
|
-
composerPkg("brick/math")
|
|
166
|
+
composerPkg("brick/math"),
|
|
167
|
+
composerPkg("tsnc/prisma-php")
|
|
167
168
|
);
|
|
168
169
|
}
|
|
169
170
|
try {
|
|
@@ -203,6 +204,7 @@ const composerPinnedVersions = {
|
|
|
203
204
|
"calicastle/cuid": "^2.0.0",
|
|
204
205
|
"symfony/uid": "^7.2.0",
|
|
205
206
|
"brick/math": "^0.13.1",
|
|
207
|
+
"tsnc/prisma-php": "^1.0.0",
|
|
206
208
|
};
|
|
207
209
|
function composerPkg(name) {
|
|
208
210
|
return composerPinnedVersions[name]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace Lib\Prisma\Classes;
|
|
4
4
|
|
|
5
|
-
use
|
|
5
|
+
use PPHP\Validator;
|
|
6
6
|
use ReflectionClass;
|
|
7
7
|
use Exception;
|
|
8
8
|
use PDO;
|
|
@@ -476,107 +476,93 @@ final class PPHPUtility
|
|
|
476
476
|
}
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
$
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
}
|
|
508
|
-
if (isset($criteria['_min'])) {
|
|
509
|
-
foreach ($criteria['_min'] as $column => $enabled) {
|
|
510
|
-
if ($enabled) {
|
|
511
|
-
$selectParts[] = "MIN($tableName." . self::quoteColumnName($dbType, $column) . ") AS min_$column";
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
if (isset($criteria['_count'])) {
|
|
516
|
-
foreach ($criteria['_count'] as $column => $enabled) {
|
|
517
|
-
if ($enabled) {
|
|
518
|
-
$selectParts[] = "COUNT($tableName." . self::quoteColumnName($dbType, $column) . ") AS count_$column";
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (isset($criteria['_avg'])) {
|
|
523
|
-
foreach ($criteria['_avg'] as $column => $enabled) {
|
|
524
|
-
if ($enabled) {
|
|
525
|
-
$selectParts[] = "AVG($tableName." . self::quoteColumnName($dbType, $column) . ") AS avg_$column";
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
if (isset($criteria['_sum'])) {
|
|
530
|
-
foreach ($criteria['_sum'] as $column => $enabled) {
|
|
531
|
-
if ($enabled) {
|
|
532
|
-
$selectParts[] = "SUM($tableName." . self::quoteColumnName($dbType, $column) . ") AS sum_$column";
|
|
479
|
+
public static function queryOptions(
|
|
480
|
+
array $criteria,
|
|
481
|
+
string &$sql,
|
|
482
|
+
string $dbType,
|
|
483
|
+
string $tableName,
|
|
484
|
+
bool $addAggregates = true
|
|
485
|
+
): void {
|
|
486
|
+
|
|
487
|
+
if ($addAggregates) {
|
|
488
|
+
$selectParts = [];
|
|
489
|
+
|
|
490
|
+
foreach (
|
|
491
|
+
[
|
|
492
|
+
'_max' => 'MAX',
|
|
493
|
+
'_min' => 'MIN',
|
|
494
|
+
'_count' => 'COUNT',
|
|
495
|
+
'_avg' => 'AVG',
|
|
496
|
+
'_sum' => 'SUM'
|
|
497
|
+
] as $key => $func
|
|
498
|
+
) {
|
|
499
|
+
|
|
500
|
+
if (!isset($criteria[$key])) continue;
|
|
501
|
+
|
|
502
|
+
foreach ($criteria[$key] as $col => $enabled) {
|
|
503
|
+
if (!$enabled) continue;
|
|
504
|
+
$alias = strtolower(substr($key, 1)) . "_$col";
|
|
505
|
+
$quoted = self::quoteColumnName($dbType, $col);
|
|
506
|
+
$selectParts[] = "$func($tableName.$quoted) AS $alias";
|
|
533
507
|
}
|
|
534
508
|
}
|
|
535
|
-
}
|
|
536
509
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
510
|
+
if ($selectParts) {
|
|
511
|
+
$sql = str_replace(
|
|
512
|
+
'SELECT',
|
|
513
|
+
'SELECT ' . implode(', ', $selectParts) . ',',
|
|
514
|
+
$sql
|
|
515
|
+
);
|
|
516
|
+
}
|
|
540
517
|
}
|
|
541
518
|
|
|
542
|
-
// Handle ORDER BY
|
|
543
519
|
if (isset($criteria['orderBy'])) {
|
|
544
|
-
$
|
|
545
|
-
if (
|
|
546
|
-
$sql .=
|
|
520
|
+
$parts = self::parseOrderBy($criteria['orderBy'], $dbType, $tableName);
|
|
521
|
+
if ($parts) {
|
|
522
|
+
$sql .= ' ORDER BY ' . implode(', ', $parts);
|
|
547
523
|
}
|
|
548
524
|
}
|
|
549
525
|
|
|
550
|
-
// Handle LIMIT (take)
|
|
551
526
|
if (isset($criteria['take'])) {
|
|
552
|
-
$sql .=
|
|
527
|
+
$sql .= ' LIMIT ' . intval($criteria['take']);
|
|
553
528
|
}
|
|
554
|
-
|
|
555
|
-
// Handle OFFSET (skip)
|
|
556
529
|
if (isset($criteria['skip'])) {
|
|
557
|
-
$sql .=
|
|
530
|
+
$sql .= ' OFFSET ' . intval($criteria['skip']);
|
|
558
531
|
}
|
|
559
532
|
}
|
|
560
533
|
|
|
561
|
-
private static function parseOrderBy(
|
|
562
|
-
|
|
563
|
-
$
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
534
|
+
private static function parseOrderBy(
|
|
535
|
+
array $orderBy,
|
|
536
|
+
string $dbType,
|
|
537
|
+
string $tableName
|
|
538
|
+
): array {
|
|
539
|
+
$aggKeys = ['_count', '_avg', '_sum', '_min', '_max'];
|
|
540
|
+
$parts = [];
|
|
541
|
+
|
|
542
|
+
foreach ($orderBy as $key => $value) {
|
|
543
|
+
|
|
544
|
+
if (in_array($key, $aggKeys, true) && is_array($value)) {
|
|
545
|
+
foreach ($value as $field => $dir) {
|
|
546
|
+
$alias = strtolower(substr($key, 1)) . '_' . $field;
|
|
547
|
+
$quoted = self::quoteColumnName($dbType, $alias);
|
|
548
|
+
$parts[] = $quoted . ' ' . (strtolower($dir) === 'desc' ? 'DESC' : 'ASC');
|
|
549
|
+
}
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (is_array($value)) {
|
|
554
|
+
foreach ($value as $nested => $dir) {
|
|
555
|
+
$dir = strtolower($dir) === 'desc' ? 'DESC' : 'ASC';
|
|
556
|
+
$parts[] = self::quoteColumnName($dbType, $key) . '.' .
|
|
557
|
+
self::quoteColumnName($dbType, $nested) . " $dir";
|
|
571
558
|
}
|
|
572
559
|
} else {
|
|
573
|
-
|
|
574
|
-
$
|
|
575
|
-
$orderByParts[] = "$tableName." . self::quoteColumnName($dbType, $column) . " $direction";
|
|
560
|
+
$dir = strtolower($value) === 'desc' ? 'DESC' : 'ASC';
|
|
561
|
+
$parts[] = "$tableName." . self::quoteColumnName($dbType, $key) . " $dir";
|
|
576
562
|
}
|
|
577
563
|
}
|
|
578
564
|
|
|
579
|
-
return $
|
|
565
|
+
return $parts;
|
|
580
566
|
}
|
|
581
567
|
|
|
582
568
|
/**
|
|
@@ -1482,4 +1468,79 @@ final class PPHPUtility
|
|
|
1482
1468
|
}
|
|
1483
1469
|
throw new Exception('Unable to determine ID field for implicit many‑to‑many lookup.');
|
|
1484
1470
|
}
|
|
1471
|
+
|
|
1472
|
+
public static function sqlOperator(string $op): string
|
|
1473
|
+
{
|
|
1474
|
+
return match ($op) {
|
|
1475
|
+
'equals', '=' => '=',
|
|
1476
|
+
'gt' => '>',
|
|
1477
|
+
'gte' => '>=',
|
|
1478
|
+
'lt' => '<',
|
|
1479
|
+
'lte' => '<=',
|
|
1480
|
+
'not' => '<>',
|
|
1481
|
+
'in' => 'IN',
|
|
1482
|
+
'notIn' => 'NOT IN',
|
|
1483
|
+
'between' => 'BETWEEN',
|
|
1484
|
+
default => throw new Exception("Unsupported operator '$op' in HAVING.")
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
public static function buildHavingClause(
|
|
1489
|
+
array $having,
|
|
1490
|
+
array $aggMap,
|
|
1491
|
+
string $dbType,
|
|
1492
|
+
array &$bindings
|
|
1493
|
+
): string {
|
|
1494
|
+
if ($having === []) {
|
|
1495
|
+
return '';
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
$useAlias = $dbType !== 'pgsql';
|
|
1499
|
+
$clauses = [];
|
|
1500
|
+
|
|
1501
|
+
foreach ($having as $aggKey => $fields) {
|
|
1502
|
+
if (!isset($aggMap[$aggKey])) {
|
|
1503
|
+
throw new Exception("Unknown aggregate '$aggKey' in 'having'.");
|
|
1504
|
+
}
|
|
1505
|
+
$sqlFunc = $aggMap[$aggKey];
|
|
1506
|
+
|
|
1507
|
+
foreach ($fields as $field => $comparators) {
|
|
1508
|
+
$alias = strtolower(substr($aggKey, 1)) . '_' . $field;
|
|
1509
|
+
$qf = self::quoteColumnName($dbType, $field);
|
|
1510
|
+
$expr = $useAlias ? $alias : "$sqlFunc($qf)";
|
|
1511
|
+
|
|
1512
|
+
foreach ($comparators as $op => $value) {
|
|
1513
|
+
$sqlOp = self::sqlOperator($op);
|
|
1514
|
+
|
|
1515
|
+
if ($sqlOp === 'BETWEEN') {
|
|
1516
|
+
if (!is_array($value) || count($value) !== 2) {
|
|
1517
|
+
throw new Exception("Operator 'between' expects exactly two values for '$alias'.");
|
|
1518
|
+
}
|
|
1519
|
+
$p1 = ':h' . count($bindings) . 'a';
|
|
1520
|
+
$p2 = ':h' . count($bindings) . 'b';
|
|
1521
|
+
$bindings[$p1] = $value[0];
|
|
1522
|
+
$bindings[$p2] = $value[1];
|
|
1523
|
+
$clauses[] = "$expr BETWEEN $p1 AND $p2";
|
|
1524
|
+
} elseif (in_array($sqlOp, ['IN', 'NOT IN'], true)) {
|
|
1525
|
+
if (!is_array($value) || $value === []) {
|
|
1526
|
+
throw new Exception("Operator '$op' expects a non-empty array for '$alias'.");
|
|
1527
|
+
}
|
|
1528
|
+
$phs = [];
|
|
1529
|
+
foreach ($value as $v) {
|
|
1530
|
+
$p = ':h' . count($bindings);
|
|
1531
|
+
$bindings[$p] = $v;
|
|
1532
|
+
$phs[] = $p;
|
|
1533
|
+
}
|
|
1534
|
+
$clauses[] = "$expr $sqlOp (" . implode(', ', $phs) . ')';
|
|
1535
|
+
} else {
|
|
1536
|
+
$p = ':h' . count($bindings);
|
|
1537
|
+
$bindings[$p] = $value;
|
|
1538
|
+
$clauses[] = "$expr $sqlOp $p";
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
return $clauses ? ' HAVING ' . implode(' AND ', $clauses) : '';
|
|
1545
|
+
}
|
|
1485
1546
|
}
|
package/package.json
CHANGED