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,438 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Query Hint Support
|
|
4
|
+
* Provides functionality to add database-specific query hints to optimize query execution
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.HintTypeExtended = exports.QueryHintManager = exports.MAX_EXECUTION_TIME = exports.SQL_NO_CACHE = exports.SQL_CACHE = exports.SQL_BUFFER_RESULT = exports.SQL_SMALL_RESULT = exports.SQL_BIG_RESULT = exports.NESTED_LOOP = exports.NO_MERGE = exports.MERGE_HASH = exports.JOIN_FIXED_ORDER = exports.USE_INDEX = exports.FORCE_INDEX = exports.INDEX_HINT = exports.HintType = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Types of query hints supported
|
|
10
|
+
*/
|
|
11
|
+
var HintType;
|
|
12
|
+
(function (HintType) {
|
|
13
|
+
/** Force use of a specific index */
|
|
14
|
+
HintType["FORCE_INDEX"] = "FORCE INDEX";
|
|
15
|
+
/** Suggest using a specific index */
|
|
16
|
+
HintType["USE_INDEX"] = "USE INDEX";
|
|
17
|
+
/** Ignore certain indexes */
|
|
18
|
+
HintType["IGNORE_INDEX"] = "IGNORE INDEX";
|
|
19
|
+
/** Force join order */
|
|
20
|
+
HintType["JOIN_FIXED_ORDER"] = "JOIN_FIXED_ORDER";
|
|
21
|
+
/** Force hash join */
|
|
22
|
+
HintType["MERGE_HASH"] = "MERGE_HASH";
|
|
23
|
+
/** Disable merge join */
|
|
24
|
+
HintType["NO_MERGE"] = "NO_MERGE";
|
|
25
|
+
/** Use nested loop join */
|
|
26
|
+
HintType["NESTED_LOOP"] = "NESTED_LOOP";
|
|
27
|
+
/** Maximum execution time in seconds */
|
|
28
|
+
HintType["MAX_EXECUTION_TIME"] = "MAX_EXECUTION_TIME";
|
|
29
|
+
/** SQL_BIG_RESULT hint */
|
|
30
|
+
HintType["SQL_BIG_RESULT"] = "SQL_BIG_RESULT";
|
|
31
|
+
/** SQL_SMALL_RESULT hint */
|
|
32
|
+
HintType["SQL_SMALL_RESULT"] = "SQL_SMALL_RESULT";
|
|
33
|
+
/** PostgreSQL: Sequential scan */
|
|
34
|
+
HintType["SEQ_SCAN"] = "SEQ_SCAN";
|
|
35
|
+
/** PostgreSQL: No sequential scan */
|
|
36
|
+
HintType["NO_SEQ_SCAN"] = "NO_SEQ_SCAN";
|
|
37
|
+
/** PostgreSQL: Index scan */
|
|
38
|
+
HintType["INDEX_SCAN"] = "INDEX_SCAN";
|
|
39
|
+
/** PostgreSQL: No index scan */
|
|
40
|
+
HintType["NO_INDEX_SCAN"] = "NO_INDEX_SCAN";
|
|
41
|
+
/** SQLite: Optimize query */
|
|
42
|
+
HintType["OPTIMIZE"] = "OPTIMIZE";
|
|
43
|
+
/** SQLite: Query plan */
|
|
44
|
+
HintType["QUERY_PLAN"] = "QUERY_PLAN";
|
|
45
|
+
/** SQL_BUFFER_RESULT hint */
|
|
46
|
+
HintType["SQL_BUFFER_RESULT"] = "SQL_BUFFER_RESULT";
|
|
47
|
+
/** SQL_CACHE hint (MySQL query cache) */
|
|
48
|
+
HintType["SQL_CACHE"] = "SQL_CACHE";
|
|
49
|
+
/** SQL_NO_CACHE hint */
|
|
50
|
+
HintType["SQL_NO_CACHE"] = "SQL_NO_CACHE";
|
|
51
|
+
/** Index merge hints */
|
|
52
|
+
HintType["INDEX_MERGE"] = "INDEX_MERGE";
|
|
53
|
+
/** Subquery optimization hints */
|
|
54
|
+
HintType["SUBQUERY"] = "SUBQUERY";
|
|
55
|
+
})(HintType || (exports.HintType = HintType = {}));
|
|
56
|
+
/**
|
|
57
|
+
* Standard index hint for MySQL/MariaDB
|
|
58
|
+
*/
|
|
59
|
+
exports.INDEX_HINT = {
|
|
60
|
+
FORCE: (indexName, tableName) => ({
|
|
61
|
+
type: HintType.FORCE_INDEX,
|
|
62
|
+
value: indexName,
|
|
63
|
+
tableName,
|
|
64
|
+
}),
|
|
65
|
+
USE: (indexName, tableName) => ({
|
|
66
|
+
type: HintType.USE_INDEX,
|
|
67
|
+
value: indexName,
|
|
68
|
+
tableName,
|
|
69
|
+
}),
|
|
70
|
+
IGNORE: (indexName, tableName) => ({
|
|
71
|
+
type: HintType.IGNORE_INDEX,
|
|
72
|
+
value: indexName,
|
|
73
|
+
tableName,
|
|
74
|
+
}),
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Predefined query hints
|
|
78
|
+
*/
|
|
79
|
+
exports.FORCE_INDEX = exports.INDEX_HINT.FORCE;
|
|
80
|
+
exports.USE_INDEX = exports.INDEX_HINT.USE;
|
|
81
|
+
exports.JOIN_FIXED_ORDER = { type: HintType.JOIN_FIXED_ORDER };
|
|
82
|
+
exports.MERGE_HASH = { type: HintType.MERGE_HASH };
|
|
83
|
+
exports.NO_MERGE = { type: HintType.NO_MERGE };
|
|
84
|
+
exports.NESTED_LOOP = { type: HintType.NESTED_LOOP };
|
|
85
|
+
exports.SQL_BIG_RESULT = { type: HintType.SQL_BIG_RESULT };
|
|
86
|
+
exports.SQL_SMALL_RESULT = { type: HintType.SQL_SMALL_RESULT };
|
|
87
|
+
exports.SQL_BUFFER_RESULT = { type: HintType.SQL_BUFFER_RESULT };
|
|
88
|
+
exports.SQL_CACHE = { type: HintType.SQL_CACHE };
|
|
89
|
+
exports.SQL_NO_CACHE = { type: HintType.SQL_NO_CACHE };
|
|
90
|
+
/**
|
|
91
|
+
* Maximum execution time hint
|
|
92
|
+
*/
|
|
93
|
+
const MAX_EXECUTION_TIME = (seconds) => ({
|
|
94
|
+
type: HintType.MAX_EXECUTION_TIME,
|
|
95
|
+
value: seconds,
|
|
96
|
+
});
|
|
97
|
+
exports.MAX_EXECUTION_TIME = MAX_EXECUTION_TIME;
|
|
98
|
+
/**
|
|
99
|
+
* Query hint manager for applying hints to SQL queries
|
|
100
|
+
*/
|
|
101
|
+
class QueryHintManager {
|
|
102
|
+
constructor(dialect, options) {
|
|
103
|
+
this.enabled = true;
|
|
104
|
+
this.dialect = dialect;
|
|
105
|
+
this.enabled = options?.enabled ?? true;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Enable or disable query hints
|
|
109
|
+
*/
|
|
110
|
+
setEnabled(enabled) {
|
|
111
|
+
this.enabled = enabled;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if hints are enabled
|
|
115
|
+
*/
|
|
116
|
+
isEnabled() {
|
|
117
|
+
return this.enabled;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Apply query hints to a SQL query
|
|
121
|
+
* @param sql - The base SQL query
|
|
122
|
+
* @param hints - Array of query hints to apply
|
|
123
|
+
* @returns SQL with hints applied
|
|
124
|
+
*/
|
|
125
|
+
applyHints(sql, hints) {
|
|
126
|
+
if (!this.enabled || hints.length === 0) {
|
|
127
|
+
return sql;
|
|
128
|
+
}
|
|
129
|
+
const dialectName = this.dialect.name.toLowerCase();
|
|
130
|
+
// Filter hints based on dialect support
|
|
131
|
+
const applicableHints = hints.filter((hint) => this.isHintSupported(hint, dialectName));
|
|
132
|
+
if (applicableHints.length === 0) {
|
|
133
|
+
return sql;
|
|
134
|
+
}
|
|
135
|
+
// SQL Server doesn't support the `/*+ ... */` comment-hint syntax used by the
|
|
136
|
+
// other dialects here; join hints are expressed as an `OPTION (...)` clause
|
|
137
|
+
// appended to the very end of the statement instead.
|
|
138
|
+
if (dialectName === 'mssql') {
|
|
139
|
+
const optionClause = this.buildMssqlOptionClause(applicableHints);
|
|
140
|
+
return optionClause ? `${sql} ${optionClause}` : sql;
|
|
141
|
+
}
|
|
142
|
+
// Build the hint comment
|
|
143
|
+
const hintComment = this.buildHintComment(applicableHints, dialectName);
|
|
144
|
+
if (!hintComment) {
|
|
145
|
+
return sql;
|
|
146
|
+
}
|
|
147
|
+
// Insert hint after SELECT keyword
|
|
148
|
+
const selectMatch = sql.match(/^(\s*SELECT\s+)/i);
|
|
149
|
+
if (selectMatch) {
|
|
150
|
+
const insertPosition = selectMatch[1].length;
|
|
151
|
+
return sql.slice(0, insertPosition) + hintComment + ' ' + sql.slice(insertPosition);
|
|
152
|
+
}
|
|
153
|
+
// For non-SELECT queries, prepend as comment
|
|
154
|
+
return hintComment + ' ' + sql;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if a hint is supported by the current dialect
|
|
158
|
+
*/
|
|
159
|
+
isHintSupported(hint, dialectName) {
|
|
160
|
+
const mysqlMariaHints = [
|
|
161
|
+
HintType.FORCE_INDEX,
|
|
162
|
+
HintType.USE_INDEX,
|
|
163
|
+
HintType.IGNORE_INDEX,
|
|
164
|
+
HintType.JOIN_FIXED_ORDER,
|
|
165
|
+
HintType.MAX_EXECUTION_TIME,
|
|
166
|
+
HintType.SQL_BIG_RESULT,
|
|
167
|
+
HintType.SQL_SMALL_RESULT,
|
|
168
|
+
HintType.SQL_BUFFER_RESULT,
|
|
169
|
+
HintType.SQL_CACHE,
|
|
170
|
+
HintType.SQL_NO_CACHE,
|
|
171
|
+
HintType.INDEX_MERGE,
|
|
172
|
+
];
|
|
173
|
+
const postgresHints = [
|
|
174
|
+
HintType.MAX_EXECUTION_TIME,
|
|
175
|
+
HintTypeExtended.SEQ_SCAN,
|
|
176
|
+
HintTypeExtended.NO_SEQ_SCAN,
|
|
177
|
+
HintTypeExtended.INDEX_SCAN,
|
|
178
|
+
HintTypeExtended.NO_INDEX_SCAN,
|
|
179
|
+
];
|
|
180
|
+
const sqliteHints = [HintTypeExtended.OPTIMIZE, HintTypeExtended.QUERY_PLAN];
|
|
181
|
+
// Oracle and SQL Server both have real optimizer hints for forcing/disabling
|
|
182
|
+
// specific join strategies (Oracle: USE_NL/USE_HASH/NO_MERGE hints; SQL Server:
|
|
183
|
+
// the LOOP/HASH/MERGE JOIN query hints via OPTION()). No other hint types in
|
|
184
|
+
// this file are implemented for these two dialects yet, so only these three
|
|
185
|
+
// are declared supported here rather than silently falling through to `false`
|
|
186
|
+
// for hints that are simply unimplemented and being misread as "unsupported".
|
|
187
|
+
const oracleHints = [HintType.NESTED_LOOP, HintType.MERGE_HASH, HintType.NO_MERGE];
|
|
188
|
+
const mssqlHints = [HintType.NESTED_LOOP, HintType.MERGE_HASH, HintType.NO_MERGE];
|
|
189
|
+
switch (dialectName) {
|
|
190
|
+
case 'mysql':
|
|
191
|
+
case 'mariadb':
|
|
192
|
+
return mysqlMariaHints.includes(hint.type);
|
|
193
|
+
case 'postgres':
|
|
194
|
+
case 'postgresql':
|
|
195
|
+
return postgresHints.includes(hint.type);
|
|
196
|
+
case 'sqlite':
|
|
197
|
+
return sqliteHints.includes(hint.type);
|
|
198
|
+
case 'oracle':
|
|
199
|
+
return oracleHints.includes(hint.type);
|
|
200
|
+
case 'mssql':
|
|
201
|
+
return mssqlHints.includes(hint.type);
|
|
202
|
+
default:
|
|
203
|
+
// Honest "no support" answer for any dialect not handled above (e.g.
|
|
204
|
+
// unknown/custom dialects), rather than an implicit gap.
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Build the hint comment string for the dialect
|
|
210
|
+
*/
|
|
211
|
+
buildHintComment(hints, dialectName) {
|
|
212
|
+
switch (dialectName) {
|
|
213
|
+
case 'mysql':
|
|
214
|
+
case 'mariadb':
|
|
215
|
+
return this.buildMySQLHints(hints);
|
|
216
|
+
case 'postgres':
|
|
217
|
+
case 'postgresql':
|
|
218
|
+
return this.buildPostgresHints(hints);
|
|
219
|
+
case 'sqlite':
|
|
220
|
+
return this.buildSQLiteHints(hints);
|
|
221
|
+
case 'oracle':
|
|
222
|
+
return this.buildOracleHints(hints);
|
|
223
|
+
default:
|
|
224
|
+
return '';
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Build MySQL/MariaDB hint comments
|
|
229
|
+
*/
|
|
230
|
+
buildMySQLHints(hints) {
|
|
231
|
+
const hintParts = [];
|
|
232
|
+
for (const hint of hints) {
|
|
233
|
+
switch (hint.type) {
|
|
234
|
+
case HintType.FORCE_INDEX:
|
|
235
|
+
case HintType.USE_INDEX:
|
|
236
|
+
case HintType.IGNORE_INDEX: {
|
|
237
|
+
const indexList = Array.isArray(hint.value) ? hint.value.join(', ') : String(hint.value);
|
|
238
|
+
const tableRef = hint.tableName ? ` ${this.dialect.quoteTable(hint.tableName)}` : '';
|
|
239
|
+
hintParts.push(`${hint.type} (${indexList})${tableRef}`);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case HintType.JOIN_FIXED_ORDER:
|
|
243
|
+
hintParts.push('JOIN_FIXED_ORDER()');
|
|
244
|
+
break;
|
|
245
|
+
case HintType.MAX_EXECUTION_TIME:
|
|
246
|
+
hintParts.push(`MAX_EXECUTION_TIME(${hint.value})`);
|
|
247
|
+
break;
|
|
248
|
+
case HintType.SQL_BIG_RESULT:
|
|
249
|
+
hintParts.push('SQL_BIG_RESULT()');
|
|
250
|
+
break;
|
|
251
|
+
case HintType.SQL_SMALL_RESULT:
|
|
252
|
+
hintParts.push('SQL_SMALL_RESULT()');
|
|
253
|
+
break;
|
|
254
|
+
case HintType.SQL_BUFFER_RESULT:
|
|
255
|
+
hintParts.push('SQL_BUFFER_RESULT()');
|
|
256
|
+
break;
|
|
257
|
+
case HintType.SQL_CACHE:
|
|
258
|
+
hintParts.push('SQL_CACHE()');
|
|
259
|
+
break;
|
|
260
|
+
case HintType.SQL_NO_CACHE:
|
|
261
|
+
hintParts.push('SQL_NO_CACHE()');
|
|
262
|
+
break;
|
|
263
|
+
case HintType.INDEX_MERGE: {
|
|
264
|
+
const indexList = Array.isArray(hint.value) ? hint.value.join(', ') : String(hint.value);
|
|
265
|
+
hintParts.push(`INDEX_MERGE(${indexList})`);
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return hintParts.length > 0 ? `/*+ ${hintParts.join(' ')} */` : '';
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Build PostgreSQL hint comments (using pg_hint_plan format)
|
|
274
|
+
*/
|
|
275
|
+
buildPostgresHints(hints) {
|
|
276
|
+
const hintParts = [];
|
|
277
|
+
for (const hint of hints) {
|
|
278
|
+
switch (hint.type) {
|
|
279
|
+
case HintType.MAX_EXECUTION_TIME:
|
|
280
|
+
hintParts.push(`SET LOCAL statement_timeout = ${Number(hint.value) * 1000}`);
|
|
281
|
+
break;
|
|
282
|
+
// PostgreSQL uses pg_hint_plan for other hints
|
|
283
|
+
// These would need pg_hint_plan extension installed
|
|
284
|
+
case HintTypeExtended.SEQ_SCAN:
|
|
285
|
+
hintParts.push('SeqScan on');
|
|
286
|
+
break;
|
|
287
|
+
case HintTypeExtended.NO_SEQ_SCAN:
|
|
288
|
+
hintParts.push('SeqScan off');
|
|
289
|
+
break;
|
|
290
|
+
case HintTypeExtended.INDEX_SCAN:
|
|
291
|
+
hintParts.push('IndexScan on');
|
|
292
|
+
break;
|
|
293
|
+
case HintTypeExtended.NO_INDEX_SCAN:
|
|
294
|
+
hintParts.push('IndexScan off');
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// PostgreSQL hints are in a different format
|
|
299
|
+
return hintParts.length > 0 ? `/*+ ${hintParts.join(' ')} */` : '';
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Build SQLite hint comments
|
|
303
|
+
*/
|
|
304
|
+
buildSQLiteHints(hints) {
|
|
305
|
+
const hintParts = [];
|
|
306
|
+
for (const hint of hints) {
|
|
307
|
+
switch (hint.type) {
|
|
308
|
+
case HintTypeExtended.OPTIMIZE:
|
|
309
|
+
hintParts.push(`OPTIMIZE ${hint.value || ''}`);
|
|
310
|
+
break;
|
|
311
|
+
case HintTypeExtended.QUERY_PLAN:
|
|
312
|
+
hintParts.push('QUERY_PLAN');
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return hintParts.length > 0 ? `/*+ ${hintParts.join(' ')} */` : '';
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Build Oracle hint comments (placed immediately after SELECT/INSERT/UPDATE/DELETE,
|
|
320
|
+
* same position as the MySQL/PostgreSQL comment hints).
|
|
321
|
+
* - USE_NL: force a nested loop join
|
|
322
|
+
* - USE_HASH: force a hash join
|
|
323
|
+
* - NO_MERGE: Oracle's real NO_MERGE hint (prevents view merging); used here as
|
|
324
|
+
* the closest real Oracle equivalent for "disable merge join"
|
|
325
|
+
*/
|
|
326
|
+
buildOracleHints(hints) {
|
|
327
|
+
const hintParts = [];
|
|
328
|
+
for (const hint of hints) {
|
|
329
|
+
switch (hint.type) {
|
|
330
|
+
case HintType.NESTED_LOOP:
|
|
331
|
+
hintParts.push(hint.tableName ? `USE_NL(${hint.tableName})` : 'USE_NL');
|
|
332
|
+
break;
|
|
333
|
+
case HintType.MERGE_HASH:
|
|
334
|
+
hintParts.push(hint.tableName ? `USE_HASH(${hint.tableName})` : 'USE_HASH');
|
|
335
|
+
break;
|
|
336
|
+
case HintType.NO_MERGE:
|
|
337
|
+
hintParts.push(hint.tableName ? `NO_MERGE(${hint.tableName})` : 'NO_MERGE');
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return hintParts.length > 0 ? `/*+ ${hintParts.join(' ')} */` : '';
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Build a SQL Server `OPTION (...)` query hint clause, appended to the end of
|
|
345
|
+
* the statement (SQL Server does not support inline `/*+ ... *\/` comment hints).
|
|
346
|
+
* SQL Server doesn't expose a direct "disable merge join" hint, so NO_MERGE is
|
|
347
|
+
* approximated by restricting the optimizer to HASH JOIN and LOOP JOIN, which
|
|
348
|
+
* excludes merge join from consideration.
|
|
349
|
+
*/
|
|
350
|
+
buildMssqlOptionClause(hints) {
|
|
351
|
+
const optionParts = [];
|
|
352
|
+
const addOption = (option) => {
|
|
353
|
+
if (!optionParts.includes(option)) {
|
|
354
|
+
optionParts.push(option);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
for (const hint of hints) {
|
|
358
|
+
switch (hint.type) {
|
|
359
|
+
case HintType.NESTED_LOOP:
|
|
360
|
+
addOption('LOOP JOIN');
|
|
361
|
+
break;
|
|
362
|
+
case HintType.MERGE_HASH:
|
|
363
|
+
addOption('HASH JOIN');
|
|
364
|
+
break;
|
|
365
|
+
case HintType.NO_MERGE:
|
|
366
|
+
addOption('HASH JOIN');
|
|
367
|
+
addOption('LOOP JOIN');
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return optionParts.length > 0 ? `OPTION (${optionParts.join(', ')})` : '';
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Create a hint for forcing index usage
|
|
375
|
+
*/
|
|
376
|
+
forceIndex(indexName, tableName) {
|
|
377
|
+
return { type: HintType.FORCE_INDEX, value: indexName, tableName };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Create a hint for suggesting index usage
|
|
381
|
+
*/
|
|
382
|
+
useIndex(indexName, tableName) {
|
|
383
|
+
return { type: HintType.USE_INDEX, value: indexName, tableName };
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Create a hint for ignoring certain indexes
|
|
387
|
+
*/
|
|
388
|
+
ignoreIndex(indexName, tableName) {
|
|
389
|
+
return { type: HintType.IGNORE_INDEX, value: indexName, tableName };
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Create a hint for maximum execution time
|
|
393
|
+
*/
|
|
394
|
+
maxExecutionTime(seconds) {
|
|
395
|
+
return { type: HintType.MAX_EXECUTION_TIME, value: seconds };
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Create a hint for SQL_BIG_RESULT
|
|
399
|
+
*/
|
|
400
|
+
sqlBigResult() {
|
|
401
|
+
return { type: HintType.SQL_BIG_RESULT };
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Create a hint for SQL_SMALL_RESULT
|
|
405
|
+
*/
|
|
406
|
+
sqlSmallResult() {
|
|
407
|
+
return { type: HintType.SQL_SMALL_RESULT };
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Create a hint for SQL_NO_CACHE
|
|
411
|
+
*/
|
|
412
|
+
sqlNoCache() {
|
|
413
|
+
return { type: HintType.SQL_NO_CACHE };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
exports.QueryHintManager = QueryHintManager;
|
|
417
|
+
// Add missing hint types for PostgreSQL
|
|
418
|
+
var HintTypeExtended;
|
|
419
|
+
(function (HintTypeExtended) {
|
|
420
|
+
HintTypeExtended["SEQ_SCAN"] = "SEQ_SCAN";
|
|
421
|
+
HintTypeExtended["NO_SEQ_SCAN"] = "NO_SEQ_SCAN";
|
|
422
|
+
HintTypeExtended["INDEX_SCAN"] = "INDEX_SCAN";
|
|
423
|
+
HintTypeExtended["NO_INDEX_SCAN"] = "NO_INDEX_SCAN";
|
|
424
|
+
HintTypeExtended["OPTIMIZE"] = "OPTIMIZE";
|
|
425
|
+
HintTypeExtended["QUERY_PLAN"] = "QUERY_PLAN";
|
|
426
|
+
})(HintTypeExtended || (exports.HintTypeExtended = HintTypeExtended = {}));
|
|
427
|
+
exports.default = {
|
|
428
|
+
QueryHintManager,
|
|
429
|
+
HintType,
|
|
430
|
+
INDEX_HINT: exports.INDEX_HINT,
|
|
431
|
+
FORCE_INDEX: exports.FORCE_INDEX,
|
|
432
|
+
USE_INDEX: exports.USE_INDEX,
|
|
433
|
+
JOIN_FIXED_ORDER: exports.JOIN_FIXED_ORDER,
|
|
434
|
+
MERGE_HASH: exports.MERGE_HASH,
|
|
435
|
+
NO_MERGE: exports.NO_MERGE,
|
|
436
|
+
NESTED_LOOP: exports.NESTED_LOOP,
|
|
437
|
+
MAX_EXECUTION_TIME: exports.MAX_EXECUTION_TIME,
|
|
438
|
+
};
|