ts-prorm-orm 1.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/CHANGELOG.md +1111 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/dist/audit/history-query.js +180 -0
- package/dist/audit/index.js +23 -0
- package/dist/audit/logger.js +236 -0
- package/dist/cache/cache-manager.js +84 -0
- package/dist/cache/index.js +16 -0
- package/dist/cache/redis-cluster-cache.js +557 -0
- package/dist/cli.js +2200 -0
- package/dist/compliance/audit-trail.js +68 -0
- package/dist/compliance/backup-verification.js +685 -0
- package/dist/compliance/breach-detector.js +505 -0
- package/dist/compliance/consent-record.js +227 -0
- package/dist/compliance/consent-versioning.js +331 -0
- package/dist/compliance/cross-border-log.js +530 -0
- package/dist/compliance/data-classifier.js +258 -0
- package/dist/compliance/data-lineage.js +565 -0
- package/dist/compliance/data-masker.js +303 -0
- package/dist/compliance/data-portability.js +265 -0
- package/dist/compliance/data-retention.js +195 -0
- package/dist/compliance/dsar-workflow.js +342 -0
- package/dist/compliance/field-encryption.js +223 -0
- package/dist/compliance/immutable-record.js +148 -0
- package/dist/compliance/index.js +260 -0
- package/dist/compliance/privacy-impact-assessment.js +364 -0
- package/dist/compliance/pseudonymization.js +269 -0
- package/dist/compliance/query-firewall.js +1182 -0
- package/dist/compliance/rate-limiter.js +580 -0
- package/dist/compliance/right-to-erasure.js +117 -0
- package/dist/compliance/row-level-security.js +246 -0
- package/dist/compliance/security-decorator.js +574 -0
- package/dist/compliance/security-monitor.js +525 -0
- package/dist/compliance/sensitive-data-discovery.js +476 -0
- package/dist/compliance/session-isolation.js +472 -0
- package/dist/compliance/tls-enforcer.js +108 -0
- package/dist/compliance/worm-storage.js +712 -0
- package/dist/connection-manager.js +198 -0
- package/dist/connection-pool.js +519 -0
- package/dist/decorators/audit.js +136 -0
- package/dist/decorators/belongs-to-many.js +115 -0
- package/dist/decorators/belongs-to.js +115 -0
- package/dist/decorators/check.js +435 -0
- package/dist/decorators/collate.js +329 -0
- package/dist/decorators/comment.js +205 -0
- package/dist/decorators/database-settings.js +236 -0
- package/dist/decorators/default.js +244 -0
- package/dist/decorators/encryption.js +235 -0
- package/dist/decorators/engine.js +97 -0
- package/dist/decorators/fk-constraints.js +594 -0
- package/dist/decorators/foreign-table.js +136 -0
- package/dist/decorators/generated.js +274 -0
- package/dist/decorators/has-many.js +127 -0
- package/dist/decorators/has-one.js +116 -0
- package/dist/decorators/hstore.js +129 -0
- package/dist/decorators/index.js +355 -0
- package/dist/decorators/json-column.js +83 -0
- package/dist/decorators/jsonb.js +101 -0
- package/dist/decorators/orm-decorators.js +425 -0
- package/dist/decorators/permissions.js +294 -0
- package/dist/decorators/procedure.js +210 -0
- package/dist/decorators/query-options.js +556 -0
- package/dist/decorators/range.js +167 -0
- package/dist/decorators/set-column.js +83 -0
- package/dist/decorators/spatial.js +114 -0
- package/dist/decorators/storage.js +580 -0
- package/dist/decorators/timezone.js +512 -0
- package/dist/decorators/trigger.js +90 -0
- package/dist/decorators/uuid.js +135 -0
- package/dist/decorators/view.js +258 -0
- package/dist/diagrams/chen-diagram.js +354 -0
- package/dist/diagrams/class-diagram.js +384 -0
- package/dist/diagrams/dependency-diagram.js +432 -0
- package/dist/diagrams/er-diagram.js +605 -0
- package/dist/diagrams/flow-diagram.js +394 -0
- package/dist/diagrams/gantt-diagram.js +411 -0
- package/dist/diagrams/index-diagram.js +353 -0
- package/dist/diagrams/index.js +184 -0
- package/dist/diagrams/migration-diagram.js +316 -0
- package/dist/diagrams/model-diagram.js +616 -0
- package/dist/diagrams/package-diagram.js +376 -0
- package/dist/diagrams/palette.js +85 -0
- package/dist/diagrams/relational-diagram.js +455 -0
- package/dist/diagrams/schemadoc-diagram.js +309 -0
- package/dist/diagrams/sequence-diagram.js +307 -0
- package/dist/diagrams/state-diagram.js +344 -0
- package/dist/diagrams/svg-dom.js +111 -0
- package/dist/diagrams/tree-diagram.js +250 -0
- package/dist/dialects/clickhouse/index.js +1742 -0
- package/dist/dialects/cockroachdb/index.js +4677 -0
- package/dist/dialects/cratedb/index.js +441 -0
- package/dist/dialects/databricks/index.js +517 -0
- package/dist/dialects/db2/index.js +2225 -0
- package/dist/dialects/dialect.js +720 -0
- package/dist/dialects/duckdb/index.js +2014 -0
- package/dist/dialects/exasol/index.js +357 -0
- package/dist/dialects/firebird/index.js +495 -0
- package/dist/dialects/greenplum/index.js +457 -0
- package/dist/dialects/hana/index.js +1741 -0
- package/dist/dialects/mariadb/index.js +3590 -0
- package/dist/dialects/mssql/index.js +2296 -0
- package/dist/dialects/mysql/index.js +4058 -0
- package/dist/dialects/oracle/index.js +2999 -0
- package/dist/dialects/postgres/index.js +5319 -0
- package/dist/dialects/query-stream-helper.js +152 -0
- package/dist/dialects/questdb/index.js +433 -0
- package/dist/dialects/redshift/index.js +2277 -0
- package/dist/dialects/singlestore/index.js +354 -0
- package/dist/dialects/snowflake/index.js +2082 -0
- package/dist/dialects/spanner/index.js +1768 -0
- package/dist/dialects/sqlite/index.js +3382 -0
- package/dist/dialects/tidb/index.js +377 -0
- package/dist/dialects/timescaledb/index.js +164 -0
- package/dist/dialects/trino/index.js +420 -0
- package/dist/dialects/turso/index.js +227 -0
- package/dist/dialects/vertica/index.js +317 -0
- package/dist/dialects/yugabytedb/index.js +424 -0
- package/dist/errors/index.js +472 -0
- package/dist/errors/utils.js +340 -0
- package/dist/errors.js +21 -0
- package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
- package/dist/extensions/catalog/mssql-features.js +147 -0
- package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
- package/dist/extensions/catalog/oracle-db2-features.js +196 -0
- package/dist/extensions/catalog/postgres-extensions.js +516 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/types.js +13 -0
- package/dist/foreign-data.js +173 -0
- package/dist/hooks/hooks-manager.js +350 -0
- package/dist/hooks/index.js +37 -0
- package/dist/index.js +463 -0
- package/dist/logging.js +335 -0
- package/dist/migrations/index.js +40 -0
- package/dist/migrations/migration.js +196 -0
- package/dist/migrations/migrator.js +411 -0
- package/dist/migrations/prormmigration.js +275 -0
- package/dist/migrations/query-interface.js +435 -0
- package/dist/migrations/seeder.js +353 -0
- package/dist/models/associations.js +852 -0
- package/dist/models/constraints.js +288 -0
- package/dist/models/data-types.js +2518 -0
- package/dist/models/decorators.js +445 -0
- package/dist/models/index.js +33 -0
- package/dist/models/indexes.js +531 -0
- package/dist/models/methods.js +382 -0
- package/dist/models/model-manager.js +103 -0
- package/dist/models/model.js +5349 -0
- package/dist/models/operators.js +67 -0
- package/dist/models/scopes.js +189 -0
- package/dist/models/typescript-types.js +26 -0
- package/dist/nosql/aerospike/index.js +205 -0
- package/dist/nosql/allegrograph/index.js +169 -0
- package/dist/nosql/arangodb/index.js +364 -0
- package/dist/nosql/azure-blob/index.js +206 -0
- package/dist/nosql/beanstalkd/index.js +231 -0
- package/dist/nosql/beequeue/index.js +210 -0
- package/dist/nosql/bigchaindb/index.js +195 -0
- package/dist/nosql/bigtable/index.js +224 -0
- package/dist/nosql/blazegraph/index.js +173 -0
- package/dist/nosql/bullmq/index.js +191 -0
- package/dist/nosql/cassandra/index.js +174 -0
- package/dist/nosql/chroma/index.js +190 -0
- package/dist/nosql/cloudflare-kv/index.js +220 -0
- package/dist/nosql/coherence/index.js +200 -0
- package/dist/nosql/cosmosdb/index.js +157 -0
- package/dist/nosql/couchbase/index.js +213 -0
- package/dist/nosql/dax/index.js +212 -0
- package/dist/nosql/deno-kv/index.js +206 -0
- package/dist/nosql/dgraph/index.js +171 -0
- package/dist/nosql/doris/index.js +169 -0
- package/dist/nosql/druid/index.js +162 -0
- package/dist/nosql/dynamodb/index.js +937 -0
- package/dist/nosql/elasticsearch/index.js +377 -0
- package/dist/nosql/etcd/index.js +502 -0
- package/dist/nosql/eventhubs/index.js +213 -0
- package/dist/nosql/eventstore/index.js +254 -0
- package/dist/nosql/faunadb/index.js +188 -0
- package/dist/nosql/firestore/index.js +177 -0
- package/dist/nosql/fluree/index.js +148 -0
- package/dist/nosql/fuseki/index.js +170 -0
- package/dist/nosql/gcs/index.js +172 -0
- package/dist/nosql/gearman/index.js +160 -0
- package/dist/nosql/geode/index.js +196 -0
- package/dist/nosql/graphdb/index.js +169 -0
- package/dist/nosql/graylog/index.js +188 -0
- package/dist/nosql/gridgain/index.js +171 -0
- package/dist/nosql/hazelcast/index.js +162 -0
- package/dist/nosql/hbase/index.js +230 -0
- package/dist/nosql/ignite/index.js +173 -0
- package/dist/nosql/immudb/index.js +184 -0
- package/dist/nosql/index.js +232 -0
- package/dist/nosql/infinispan/index.js +200 -0
- package/dist/nosql/influxdb/index.js +0 -0
- package/dist/nosql/kafka/index.js +234 -0
- package/dist/nosql/keyspaces/index.js +189 -0
- package/dist/nosql/kinesis/index.js +253 -0
- package/dist/nosql/leveldb/index.js +153 -0
- package/dist/nosql/lmdb/index.js +160 -0
- package/dist/nosql/loki/index.js +201 -0
- package/dist/nosql/marklogic/index.js +204 -0
- package/dist/nosql/materialize/index.js +145 -0
- package/dist/nosql/meilisearch/index.js +154 -0
- package/dist/nosql/memcached/index.js +223 -0
- package/dist/nosql/milvus/index.js +410 -0
- package/dist/nosql/minio/index.js +265 -0
- package/dist/nosql/momento/index.js +179 -0
- package/dist/nosql/mongodb/index.js +461 -0
- package/dist/nosql/nats/index.js +247 -0
- package/dist/nosql/nedb/index.js +164 -0
- package/dist/nosql/neo4j/index.js +450 -0
- package/dist/nosql/neptune/index.js +470 -0
- package/dist/nosql/nsq/index.js +200 -0
- package/dist/nosql/opensearch/index.js +186 -0
- package/dist/nosql/orientdb/index.js +175 -0
- package/dist/nosql/papertrail/index.js +200 -0
- package/dist/nosql/pinecone/index.js +0 -0
- package/dist/nosql/pinot/index.js +133 -0
- package/dist/nosql/pouchdb/index.js +172 -0
- package/dist/nosql/prometheus/index.js +174 -0
- package/dist/nosql/provendb/index.js +147 -0
- package/dist/nosql/pubsub/index.js +187 -0
- package/dist/nosql/pulsar/index.js +232 -0
- package/dist/nosql/qdrant/index.js +295 -0
- package/dist/nosql/qldb/index.js +192 -0
- package/dist/nosql/r2/index.js +281 -0
- package/dist/nosql/rabbitmq/index.js +237 -0
- package/dist/nosql/ravendb/index.js +175 -0
- package/dist/nosql/redis/index.js +607 -0
- package/dist/nosql/redpanda/index.js +237 -0
- package/dist/nosql/resque/index.js +203 -0
- package/dist/nosql/rethinkdb/index.js +232 -0
- package/dist/nosql/rocksdb/index.js +152 -0
- package/dist/nosql/rockset/index.js +126 -0
- package/dist/nosql/s3/index.js +298 -0
- package/dist/nosql/scylladb/index.js +178 -0
- package/dist/nosql/signoz/index.js +227 -0
- package/dist/nosql/sns/index.js +201 -0
- package/dist/nosql/solr/index.js +231 -0
- package/dist/nosql/splunk/index.js +227 -0
- package/dist/nosql/sqs/index.js +246 -0
- package/dist/nosql/stardog/index.js +169 -0
- package/dist/nosql/starrocks/index.js +170 -0
- package/dist/nosql/store.js +2 -0
- package/dist/nosql/sumologic/index.js +213 -0
- package/dist/nosql/surrealdb/index.js +179 -0
- package/dist/nosql/terminusdb/index.js +151 -0
- package/dist/nosql/tigergraph/index.js +469 -0
- package/dist/nosql/typesense/index.js +148 -0
- package/dist/nosql/unqlite/index.js +157 -0
- package/dist/nosql/upstash/index.js +167 -0
- package/dist/nosql/vercel-kv/index.js +166 -0
- package/dist/nosql/victoriametrics/index.js +213 -0
- package/dist/nosql/virtuoso/index.js +169 -0
- package/dist/nosql/weaviate/index.js +276 -0
- package/dist/operators/index.js +108 -0
- package/dist/operators.js +2690 -0
- package/dist/prisma-migrate/index.js +38 -0
- package/dist/prisma-migrate/migration-generator.js +125 -0
- package/dist/prisma-migrate/model-generator.js +172 -0
- package/dist/prisma-migrate/relations.js +100 -0
- package/dist/prisma-migrate/schema-parser.js +167 -0
- package/dist/prisma-migrate/type-mapper.js +40 -0
- package/dist/prorm.js +6832 -0
- package/dist/query-builders/cte-builder.js +80 -0
- package/dist/query-builders/functions/aggregate.js +390 -0
- package/dist/query-builders/functions/conditional.js +503 -0
- package/dist/query-builders/functions/datetime.js +695 -0
- package/dist/query-builders/functions/fulltext.js +439 -0
- package/dist/query-builders/functions/index.js +93 -0
- package/dist/query-builders/functions/json.js +427 -0
- package/dist/query-builders/functions/math.js +399 -0
- package/dist/query-builders/functions/string.js +518 -0
- package/dist/query-builders/functions/window.js +328 -0
- package/dist/query-builders/include-builder.js +323 -0
- package/dist/query-builders/index-expression-builder.js +242 -0
- package/dist/query-builders/index.js +161 -0
- package/dist/query-builders/insert-builder.js +164 -0
- package/dist/query-builders/model-helpers.js +38 -0
- package/dist/query-builders/order-limit-builder.js +239 -0
- package/dist/query-builders/sql-compiler.js +2040 -0
- package/dist/query-builders/subquery-builder.js +152 -0
- package/dist/query-builders/update-builder.js +182 -0
- package/dist/query-builders/view-builder.js +218 -0
- package/dist/query-builders/where-builder.js +1532 -0
- package/dist/query-interface.js +622 -0
- package/dist/query-optimizers/batch-optimizer.js +426 -0
- package/dist/query-optimizers/explain-plans.js +415 -0
- package/dist/query-optimizers/index.js +51 -0
- package/dist/query-optimizers/prepared-statement-cache.js +423 -0
- package/dist/query-optimizers/query-hints.js +438 -0
- package/dist/query-optimizers/query-optimizer.js +278 -0
- package/dist/query-optimizers/slow-query-logger.js +271 -0
- package/dist/replica-manager.js +507 -0
- package/dist/schema/index.js +15 -0
- package/dist/schema/migration-generator.js +374 -0
- package/dist/schema/schema-differ.js +549 -0
- package/dist/schema/types.js +6 -0
- package/dist/sql-constants.js +300 -0
- package/dist/sqlite-advanced.js +1047 -0
- package/dist/streams/index.js +12 -0
- package/dist/streams/transforms.js +178 -0
- package/dist/transaction.js +456 -0
- package/dist/types/index.js +180 -0
- package/dist/user-management.js +127 -0
- package/dist/utils/date.js +300 -0
- package/dist/utils/index.js +1079 -0
- package/dist/utils/string.js +161 -0
- package/dist/validators/index.js +19 -0
- package/dist/validators/validator.js +911 -0
- package/package.json +190 -0
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Index and Constraint classes for the TypeScript ORM
|
|
4
|
+
* Supports single column, composite, unique, and partial indexes
|
|
5
|
+
* Supports foreign key constraints with cascade options
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ConstraintCollection = exports.IndexCollection = exports.Constraint = exports.Index = void 0;
|
|
9
|
+
exports.generateIndexName = generateIndexName;
|
|
10
|
+
exports.generateConstraintName = generateConstraintName;
|
|
11
|
+
exports.generateUniqueConstraintName = generateUniqueConstraintName;
|
|
12
|
+
exports.generateForeignKeyConstraintName = generateForeignKeyConstraintName;
|
|
13
|
+
exports.generatePrimaryKeyConstraintName = generatePrimaryKeyConstraintName;
|
|
14
|
+
exports.normalizeFields = normalizeFields;
|
|
15
|
+
exports.buildIndexSQL = buildIndexSQL;
|
|
16
|
+
exports.buildDropIndexSQL = buildDropIndexSQL;
|
|
17
|
+
exports.buildConstraintSQL = buildConstraintSQL;
|
|
18
|
+
exports.buildAddConstraintSQL = buildAddConstraintSQL;
|
|
19
|
+
exports.buildDropConstraintSQL = buildDropConstraintSQL;
|
|
20
|
+
/**
|
|
21
|
+
* Index class representing a database index
|
|
22
|
+
*/
|
|
23
|
+
class Index {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.name = options.name || '';
|
|
26
|
+
this.unique = options.unique || false;
|
|
27
|
+
this.type = options.type;
|
|
28
|
+
this.using = options.using;
|
|
29
|
+
this.algorithm = options.algorithm;
|
|
30
|
+
this.fields = this.normalizeFields(options.fields || []);
|
|
31
|
+
this.where = options.where;
|
|
32
|
+
this.include = options.include;
|
|
33
|
+
this.expression = options.expression;
|
|
34
|
+
this.tableName = options.tableName;
|
|
35
|
+
this.fulltext = options.fulltext;
|
|
36
|
+
this.spatial = options.spatial;
|
|
37
|
+
this.parser = options.parser;
|
|
38
|
+
this.textSearchConfig = options.textSearchConfig;
|
|
39
|
+
this.gistOptions = options.gistOptions;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Normalize fields to IndexField array
|
|
43
|
+
*/
|
|
44
|
+
normalizeFields(fields) {
|
|
45
|
+
return fields.map((f) => {
|
|
46
|
+
if (typeof f === 'string') {
|
|
47
|
+
return { name: f, order: 'ASC' };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
name: f.name,
|
|
51
|
+
length: f.length,
|
|
52
|
+
order: (f.order || 'ASC'),
|
|
53
|
+
collate: f.collate,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the field names as a simple string array
|
|
59
|
+
*/
|
|
60
|
+
getFieldNames() {
|
|
61
|
+
return this.fields.map((f) => f.name);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if this is a partial index
|
|
65
|
+
*/
|
|
66
|
+
isPartial() {
|
|
67
|
+
return !!this.where && Object.keys(this.where).length > 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if this is an expression index
|
|
71
|
+
*/
|
|
72
|
+
isExpression() {
|
|
73
|
+
return !!this.expression;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if this is a composite index
|
|
77
|
+
*/
|
|
78
|
+
isComposite() {
|
|
79
|
+
return this.fields.length > 1;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Convert to plain object
|
|
83
|
+
*/
|
|
84
|
+
toJSON() {
|
|
85
|
+
return {
|
|
86
|
+
name: this.name,
|
|
87
|
+
unique: this.unique,
|
|
88
|
+
type: this.type,
|
|
89
|
+
using: this.using,
|
|
90
|
+
algorithm: this.algorithm,
|
|
91
|
+
fields: this.fields,
|
|
92
|
+
where: this.where,
|
|
93
|
+
include: this.include,
|
|
94
|
+
expression: this.expression,
|
|
95
|
+
tableName: this.tableName,
|
|
96
|
+
fulltext: this.fulltext,
|
|
97
|
+
parser: this.parser,
|
|
98
|
+
textSearchConfig: this.textSearchConfig,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if this is a fulltext index
|
|
103
|
+
*/
|
|
104
|
+
isFulltext() {
|
|
105
|
+
return !!this.fulltext;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if this is a GIN index
|
|
109
|
+
*/
|
|
110
|
+
isGIN() {
|
|
111
|
+
return this.algorithm === 'gin';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.Index = Index;
|
|
115
|
+
/**
|
|
116
|
+
* Constraint class representing a database constraint
|
|
117
|
+
*/
|
|
118
|
+
class Constraint {
|
|
119
|
+
constructor(options) {
|
|
120
|
+
this.name = options.name || '';
|
|
121
|
+
this.type = options.type;
|
|
122
|
+
this.fields = options.fields || [];
|
|
123
|
+
this.references = options.references;
|
|
124
|
+
this.onDelete = options.onDelete;
|
|
125
|
+
this.onUpdate = options.onUpdate;
|
|
126
|
+
this.check = options.check;
|
|
127
|
+
this.deferrable = options.deferrable;
|
|
128
|
+
this.tableName = options.tableName;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if this is a foreign key constraint
|
|
132
|
+
*/
|
|
133
|
+
isForeignKey() {
|
|
134
|
+
return this.type === 'FOREIGN KEY';
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if this is a unique constraint
|
|
138
|
+
*/
|
|
139
|
+
isUnique() {
|
|
140
|
+
return this.type === 'UNIQUE';
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if this is a primary key constraint
|
|
144
|
+
*/
|
|
145
|
+
isPrimaryKey() {
|
|
146
|
+
return this.type === 'PRIMARY KEY';
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if this is a check constraint
|
|
150
|
+
*/
|
|
151
|
+
isCheck() {
|
|
152
|
+
return this.type === 'CHECK';
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the ON DELETE action
|
|
156
|
+
*/
|
|
157
|
+
getOnDelete() {
|
|
158
|
+
return this.onDelete;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the ON UPDATE action
|
|
162
|
+
*/
|
|
163
|
+
getOnUpdate() {
|
|
164
|
+
return this.onUpdate;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Convert to plain object
|
|
168
|
+
*/
|
|
169
|
+
toJSON() {
|
|
170
|
+
return {
|
|
171
|
+
name: this.name,
|
|
172
|
+
type: this.type,
|
|
173
|
+
fields: this.fields,
|
|
174
|
+
references: this.references,
|
|
175
|
+
onDelete: this.onDelete,
|
|
176
|
+
onUpdate: this.onUpdate,
|
|
177
|
+
check: this.check,
|
|
178
|
+
deferrable: this.deferrable,
|
|
179
|
+
tableName: this.tableName,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.Constraint = Constraint;
|
|
184
|
+
/**
|
|
185
|
+
* Generate a unique index name based on table and fields
|
|
186
|
+
*/
|
|
187
|
+
function generateIndexName(tableName, fields) {
|
|
188
|
+
const fieldNames = Array.isArray(fields)
|
|
189
|
+
? fields.map((f) => (typeof f === 'string' ? f : f.name)).join('_')
|
|
190
|
+
: fields;
|
|
191
|
+
return `idx_${tableName}_${fieldNames}`;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Generate constraint name with auto-naming convention
|
|
195
|
+
* - Primary key: table_pkey
|
|
196
|
+
* - Unique: table_field1_field2_key or custom name
|
|
197
|
+
* - Foreign key: table_field_fkey or table_field_referencedTable_fkey
|
|
198
|
+
*/
|
|
199
|
+
function generateConstraintName(tableName, type, fields, options) {
|
|
200
|
+
// If custom name is provided, use it
|
|
201
|
+
if (options?.name) {
|
|
202
|
+
return options.name;
|
|
203
|
+
}
|
|
204
|
+
const fieldStr = fields.join('_');
|
|
205
|
+
const refTable = options?.referencedTable;
|
|
206
|
+
switch (type) {
|
|
207
|
+
case 'PRIMARY KEY':
|
|
208
|
+
// Primary key: table_pkey
|
|
209
|
+
return `${tableName}_pkey`;
|
|
210
|
+
case 'UNIQUE':
|
|
211
|
+
// Unique: table_field1_field2_key or table_field_key for single field
|
|
212
|
+
if (fields.length === 1) {
|
|
213
|
+
return `${tableName}_${fields[0]}_key`;
|
|
214
|
+
}
|
|
215
|
+
return `${tableName}_${fieldStr}_key`;
|
|
216
|
+
case 'FOREIGN KEY':
|
|
217
|
+
// Foreign key: table_field_fkey or table_field_referencedTable_fkey for composite
|
|
218
|
+
if (refTable) {
|
|
219
|
+
return `${tableName}_${fieldStr}_${refTable}_fkey`;
|
|
220
|
+
}
|
|
221
|
+
return `${tableName}_${fieldStr}_fkey`;
|
|
222
|
+
case 'CHECK':
|
|
223
|
+
// Check: table_field_check
|
|
224
|
+
return `${tableName}_${fieldStr}_check`;
|
|
225
|
+
default: {
|
|
226
|
+
// This should never happen if all ConstraintType cases are handled
|
|
227
|
+
const unknownType = type;
|
|
228
|
+
return `${unknownType.toLowerCase().replace(' ', '_')}_${tableName}_${fieldStr}`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Generate unique constraint name
|
|
234
|
+
*/
|
|
235
|
+
function generateUniqueConstraintName(tableName, fields, customName) {
|
|
236
|
+
if (customName) {
|
|
237
|
+
return customName;
|
|
238
|
+
}
|
|
239
|
+
if (fields.length === 1) {
|
|
240
|
+
return `${tableName}_${fields[0]}_key`;
|
|
241
|
+
}
|
|
242
|
+
return `${tableName}_${fields.join('_')}_key`;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Generate foreign key constraint name
|
|
246
|
+
*/
|
|
247
|
+
function generateForeignKeyConstraintName(tableName, fields, referencedTable, customName) {
|
|
248
|
+
if (customName) {
|
|
249
|
+
return customName;
|
|
250
|
+
}
|
|
251
|
+
const fieldStr = fields.join('_');
|
|
252
|
+
if (referencedTable) {
|
|
253
|
+
return `${tableName}_${fieldStr}_${referencedTable}_fkey`;
|
|
254
|
+
}
|
|
255
|
+
return `${tableName}_${fieldStr}_fkey`;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Generate primary key constraint name
|
|
259
|
+
*/
|
|
260
|
+
function generatePrimaryKeyConstraintName(tableName, customName) {
|
|
261
|
+
return customName || `${tableName}_pkey`;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Normalize fields to IndexField array
|
|
265
|
+
*/
|
|
266
|
+
function normalizeFields(fields) {
|
|
267
|
+
return fields.map((f) => {
|
|
268
|
+
if (typeof f === 'string') {
|
|
269
|
+
return { name: f, order: 'ASC' };
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
name: f.name,
|
|
273
|
+
length: f.length,
|
|
274
|
+
order: (f.order || 'ASC'),
|
|
275
|
+
collate: f.collate,
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Index collection for managing multiple indexes
|
|
281
|
+
*/
|
|
282
|
+
class IndexCollection {
|
|
283
|
+
constructor() {
|
|
284
|
+
this.indexes = new Map();
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Add an index to the collection
|
|
288
|
+
*/
|
|
289
|
+
addIndex(index) {
|
|
290
|
+
if (!index.name) {
|
|
291
|
+
throw new Error('Index must have a name');
|
|
292
|
+
}
|
|
293
|
+
this.indexes.set(index.name, index);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get an index by name
|
|
297
|
+
*/
|
|
298
|
+
getIndex(name) {
|
|
299
|
+
return this.indexes.get(name);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get all indexes
|
|
303
|
+
*/
|
|
304
|
+
getAllIndexes() {
|
|
305
|
+
return Array.from(this.indexes.values());
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Remove an index by name
|
|
309
|
+
*/
|
|
310
|
+
removeIndex(name) {
|
|
311
|
+
return this.indexes.delete(name);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Check if an index exists
|
|
315
|
+
*/
|
|
316
|
+
hasIndex(name) {
|
|
317
|
+
return this.indexes.has(name);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Get the number of indexes
|
|
321
|
+
*/
|
|
322
|
+
get size() {
|
|
323
|
+
return this.indexes.size;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Clear all indexes
|
|
327
|
+
*/
|
|
328
|
+
clear() {
|
|
329
|
+
this.indexes.clear();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
exports.IndexCollection = IndexCollection;
|
|
333
|
+
/**
|
|
334
|
+
* Constraint collection for managing multiple constraints
|
|
335
|
+
*/
|
|
336
|
+
class ConstraintCollection {
|
|
337
|
+
constructor() {
|
|
338
|
+
this.constraints = new Map();
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Add a constraint to the collection
|
|
342
|
+
*/
|
|
343
|
+
addConstraint(constraint) {
|
|
344
|
+
if (!constraint.name) {
|
|
345
|
+
throw new Error('Constraint must have a name');
|
|
346
|
+
}
|
|
347
|
+
this.constraints.set(constraint.name, constraint);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get a constraint by name
|
|
351
|
+
*/
|
|
352
|
+
getConstraint(name) {
|
|
353
|
+
return this.constraints.get(name);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Get all constraints
|
|
357
|
+
*/
|
|
358
|
+
getAllConstraints() {
|
|
359
|
+
return Array.from(this.constraints.values());
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Remove a constraint by name
|
|
363
|
+
*/
|
|
364
|
+
removeConstraint(name) {
|
|
365
|
+
return this.constraints.delete(name);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Check if a constraint exists
|
|
369
|
+
*/
|
|
370
|
+
hasConstraint(name) {
|
|
371
|
+
return this.constraints.has(name);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Get the number of constraints
|
|
375
|
+
*/
|
|
376
|
+
get size() {
|
|
377
|
+
return this.constraints.size;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Clear all constraints
|
|
381
|
+
*/
|
|
382
|
+
clear() {
|
|
383
|
+
this.constraints.clear();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Get all foreign key constraints
|
|
387
|
+
*/
|
|
388
|
+
getForeignKeys() {
|
|
389
|
+
return this.getAllConstraints().filter((c) => c.isForeignKey());
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get all unique constraints
|
|
393
|
+
*/
|
|
394
|
+
getUniqueConstraints() {
|
|
395
|
+
return this.getAllConstraints().filter((c) => c.isUnique());
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
exports.ConstraintCollection = ConstraintCollection;
|
|
399
|
+
/**
|
|
400
|
+
* Build index SQL for a specific dialect
|
|
401
|
+
*/
|
|
402
|
+
function buildIndexSQL(dialect, indexName, tableName, fields, options) {
|
|
403
|
+
const escapeIdent = (name) => dialect === 'mysql' || dialect === 'mariadb' ? `\`${name}\`` : `"${name}"`;
|
|
404
|
+
const normalizedFields = normalizeFields(fields);
|
|
405
|
+
const fieldList = normalizedFields
|
|
406
|
+
.map((f) => {
|
|
407
|
+
let fieldStr = escapeIdent(f.name);
|
|
408
|
+
if (f.length) {
|
|
409
|
+
fieldStr += `(${f.length})`;
|
|
410
|
+
}
|
|
411
|
+
if (f.order) {
|
|
412
|
+
fieldStr += ` ${f.order}`;
|
|
413
|
+
}
|
|
414
|
+
return fieldStr;
|
|
415
|
+
})
|
|
416
|
+
.join(', ');
|
|
417
|
+
// Handle FULLTEXT index for MySQL/MariaDB
|
|
418
|
+
if (options?.fulltext && (dialect === 'mysql' || dialect === 'mariadb')) {
|
|
419
|
+
let sql = 'CREATE FULLTEXT';
|
|
420
|
+
if (options?.unique) {
|
|
421
|
+
sql += ' UNIQUE';
|
|
422
|
+
}
|
|
423
|
+
sql += ` INDEX ${escapeIdent(indexName)} ON ${escapeIdent(tableName)} (${fieldList})`;
|
|
424
|
+
if (options?.parser) {
|
|
425
|
+
sql += ` WITH PARSER ${options.parser}`;
|
|
426
|
+
}
|
|
427
|
+
return sql;
|
|
428
|
+
}
|
|
429
|
+
let sql = 'CREATE';
|
|
430
|
+
if (options?.unique) {
|
|
431
|
+
sql += ' UNIQUE';
|
|
432
|
+
}
|
|
433
|
+
if (options?.type) {
|
|
434
|
+
sql += ` INDEX ${options.type}`;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
sql += ' INDEX';
|
|
438
|
+
}
|
|
439
|
+
const escapedIndexName = escapeIdent(indexName);
|
|
440
|
+
const escapedTableName = escapeIdent(tableName);
|
|
441
|
+
sql += ` ${escapedIndexName} ON ${escapedTableName} (${fieldList})`;
|
|
442
|
+
// Add USING clause - algorithm takes precedence over using for PostgreSQL index algorithms
|
|
443
|
+
if (options?.algorithm) {
|
|
444
|
+
sql += ` USING ${options.algorithm}`;
|
|
445
|
+
}
|
|
446
|
+
else if (options?.using) {
|
|
447
|
+
sql += ` USING ${options.using}`;
|
|
448
|
+
}
|
|
449
|
+
return sql;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Build DROP INDEX SQL
|
|
453
|
+
*/
|
|
454
|
+
function buildDropIndexSQL(dialect, indexName, tableName) {
|
|
455
|
+
const escapeIdent = (name) => dialect === 'mysql' || dialect === 'mariadb' ? `\`${name}\`` : `"${name}"`;
|
|
456
|
+
if (dialect === 'mysql' || dialect === 'mariadb') {
|
|
457
|
+
if (!tableName) {
|
|
458
|
+
throw new Error('tableName is required for MySQL/MariaDB DROP INDEX');
|
|
459
|
+
}
|
|
460
|
+
// MySQL/MariaDB syntax: DROP INDEX index_name ON tbl_name
|
|
461
|
+
return `DROP INDEX ${escapeIdent(indexName)} ON ${escapeIdent(tableName)}`;
|
|
462
|
+
}
|
|
463
|
+
return `DROP INDEX ${escapeIdent(indexName)}`;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Build constraint SQL for a specific dialect
|
|
467
|
+
*/
|
|
468
|
+
function buildConstraintSQL(dialect, constraint, tableName) {
|
|
469
|
+
const escapeIdent = (name) => dialect === 'mysql' || dialect === 'mariadb' ? `\`${name}\`` : `"${name}"`;
|
|
470
|
+
const escapedFields = constraint.fields.map((f) => escapeIdent(f)).join(', ');
|
|
471
|
+
const escapedName = escapeIdent(constraint.name);
|
|
472
|
+
switch (constraint.type) {
|
|
473
|
+
case 'UNIQUE':
|
|
474
|
+
return `CONSTRAINT ${escapedName} UNIQUE (${escapedFields})`;
|
|
475
|
+
case 'PRIMARY KEY':
|
|
476
|
+
return `CONSTRAINT ${escapedName} PRIMARY KEY (${escapedFields})`;
|
|
477
|
+
case 'FOREIGN KEY': {
|
|
478
|
+
if (!constraint.references) {
|
|
479
|
+
throw new Error('Foreign key constraint requires references');
|
|
480
|
+
}
|
|
481
|
+
let sql = `CONSTRAINT ${escapedName} FOREIGN KEY (${escapedFields}) `;
|
|
482
|
+
sql += `REFERENCES ${escapeIdent(constraint.references.table)} (${escapeIdent(constraint.references.field)})`;
|
|
483
|
+
if (constraint.onDelete) {
|
|
484
|
+
sql += ` ON DELETE ${constraint.onDelete}`;
|
|
485
|
+
}
|
|
486
|
+
if (constraint.onUpdate) {
|
|
487
|
+
sql += ` ON UPDATE ${constraint.onUpdate}`;
|
|
488
|
+
}
|
|
489
|
+
if (constraint.deferrable) {
|
|
490
|
+
sql += ` DEFERRABLE ${constraint.deferrable}`;
|
|
491
|
+
}
|
|
492
|
+
return sql;
|
|
493
|
+
}
|
|
494
|
+
case 'CHECK':
|
|
495
|
+
if (!constraint.check) {
|
|
496
|
+
throw new Error('Check constraint requires check expression');
|
|
497
|
+
}
|
|
498
|
+
return `CONSTRAINT ${escapedName} CHECK (${constraint.check})`;
|
|
499
|
+
default:
|
|
500
|
+
throw new Error(`Unknown constraint type: ${constraint.type}`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Build ADD CONSTRAINT SQL
|
|
505
|
+
*/
|
|
506
|
+
function buildAddConstraintSQL(dialect, constraint, tableName) {
|
|
507
|
+
const escapeIdent = (name) => dialect === 'mysql' || dialect === 'mariadb' ? `\`${name}\`` : `"${name}"`;
|
|
508
|
+
const constraintSql = buildConstraintSQL(dialect, constraint, tableName);
|
|
509
|
+
return `ALTER TABLE ${escapeIdent(tableName)} ADD ${constraintSql}`;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Build DROP CONSTRAINT SQL
|
|
513
|
+
*/
|
|
514
|
+
function buildDropConstraintSQL(dialect, constraintName, tableName) {
|
|
515
|
+
const escapeIdent = (name) => dialect === 'mysql' || dialect === 'mariadb' ? `\`${name}\`` : `"${name}"`;
|
|
516
|
+
return `ALTER TABLE ${escapeIdent(tableName)} DROP CONSTRAINT ${escapeIdent(constraintName)}`;
|
|
517
|
+
}
|
|
518
|
+
exports.default = {
|
|
519
|
+
Index,
|
|
520
|
+
IndexCollection,
|
|
521
|
+
Constraint,
|
|
522
|
+
ConstraintCollection,
|
|
523
|
+
generateIndexName,
|
|
524
|
+
generateConstraintName,
|
|
525
|
+
normalizeFields,
|
|
526
|
+
buildIndexSQL,
|
|
527
|
+
buildDropIndexSQL,
|
|
528
|
+
buildConstraintSQL,
|
|
529
|
+
buildAddConstraintSQL,
|
|
530
|
+
buildDropConstraintSQL,
|
|
531
|
+
};
|