AK-21/Graphite-Industrial-Intelligence
0
1import { entityKind, is } from "../entity.js";2import { isPgEnum } from "../pg-core/columns/enum.js";3import { Subquery } from "../subquery.js";4import { tracer } from "../tracing.js";5import { ViewBaseConfig } from "../view-common.js";6import { Column } from "../column.js";7import { IsAlias, Table } from "../table.js";8class FakePrimitiveParam {9 static [entityKind] = "FakePrimitiveParam";10}11function isSQLWrapper(value) {12 return value !== null && value !== void 0 && typeof value.getSQL === "function";13}14function mergeQueries(queries) {15 const result = { sql: "", params: [] };16 for (const query of queries) {17 result.sql += query.sql;18 result.params.push(...query.params);19 if (query.typings?.length) {20 if (!result.typings) {21 result.typings = [];22 }23 result.typings.push(...query.typings);24 }25 }26 return result;27}28class StringChunk {29 static [entityKind] = "StringChunk";30 value;31 constructor(value) {32 this.value = Array.isArray(value) ? value : [value];33 }34 getSQL() {35 return new SQL([this]);36 }37}38class SQL {39 constructor(queryChunks) {40 this.queryChunks = queryChunks;41 for (const chunk of queryChunks) {42 if (is(chunk, Table)) {43 const schemaName = chunk[Table.Symbol.Schema];44 this.usedTables.push(45 schemaName === void 0 ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]46 );47 }48 }49 }50 static [entityKind] = "SQL";51 /** @internal */52 decoder = noopDecoder;53 shouldInlineParams = false;54 /** @internal */55 usedTables = [];56 append(query) {57 this.queryChunks.push(...query.queryChunks);58 return this;59 }60 toQuery(config) {61 return tracer.startActiveSpan("drizzle.buildSQL", (span) => {62 const query = this.buildQueryFromSourceParams(this.queryChunks, config);63 span?.setAttributes({64 "drizzle.query.text": query.sql,65 "drizzle.query.params": JSON.stringify(query.params)66 });67 return query;68 });69 }70 buildQueryFromSourceParams(chunks, _config) {71 const config = Object.assign({}, _config, {72 inlineParams: _config.inlineParams || this.shouldInlineParams,73 paramStartIndex: _config.paramStartIndex || { value: 0 }74 });75 const {76 casing,77 escapeName,78 escapeParam,79 prepareTyping,80 inlineParams,81 paramStartIndex82 } = config;83 return mergeQueries(chunks.map((chunk) => {84 if (is(chunk, StringChunk)) {85 return { sql: chunk.value.join(""), params: [] };86 }87 if (is(chunk, Name)) {88 return { sql: escapeName(chunk.value), params: [] };89 }90 if (chunk === void 0) {91 return { sql: "", params: [] };92 }93 if (Array.isArray(chunk)) {94 const result = [new StringChunk("(")];95 for (const [i, p] of chunk.entries()) {96 result.push(p);97 if (i < chunk.length - 1) {98 result.push(new StringChunk(", "));99 }100 }101 result.push(new StringChunk(")"));102 return this.buildQueryFromSourceParams(result, config);103 }104 if (is(chunk, SQL)) {105 return this.buildQueryFromSourceParams(chunk.queryChunks, {106 ...config,107 inlineParams: inlineParams || chunk.shouldInlineParams108 });109 }110 if (is(chunk, Table)) {111 const schemaName = chunk[Table.Symbol.Schema];112 const tableName = chunk[Table.Symbol.Name];113 return {114 sql: schemaName === void 0 || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),115 params: []116 };117 }118 if (is(chunk, Column)) {119 const columnName = casing.getColumnCasing(chunk);120 if (_config.invokeSource === "indexes") {121 return { sql: escapeName(columnName), params: [] };122 }123 const schemaName = chunk.table[Table.Symbol.Schema];124 return {125 sql: chunk.table[IsAlias] || schemaName === void 0 ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),126 params: []127 };128 }129 if (is(chunk, View)) {130 const schemaName = chunk[ViewBaseConfig].schema;131 const viewName = chunk[ViewBaseConfig].name;132 return {133 sql: schemaName === void 0 || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),134 params: []135 };136 }137 if (is(chunk, Param)) {138 if (is(chunk.value, Placeholder)) {139 return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };140 }141 const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);142 if (is(mappedValue, SQL)) {143 return this.buildQueryFromSourceParams([mappedValue], config);144 }145 if (inlineParams) {146 return { sql: this.mapInlineParam(mappedValue, config), params: [] };147 }148 let typings = ["none"];149 if (prepareTyping) {150 typings = [prepareTyping(chunk.encoder)];151 }152 return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };153 }154 if (is(chunk, Placeholder)) {155 return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };156 }157 if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== void 0) {158 return { sql: escapeName(chunk.fieldAlias), params: [] };159 }160 if (is(chunk, Subquery)) {161 if (chunk._.isWith) {162 return { sql: escapeName(chunk._.alias), params: [] };163 }164 return this.buildQueryFromSourceParams([165 new StringChunk("("),166 chunk._.sql,167 new StringChunk(") "),168 new Name(chunk._.alias)169 ], config);170 }171 if (isPgEnum(chunk)) {172 if (chunk.schema) {173 return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };174 }175 return { sql: escapeName(chunk.enumName), params: [] };176 }177 if (isSQLWrapper(chunk)) {178 if (chunk.shouldOmitSQLParens?.()) {179 return this.buildQueryFromSourceParams([chunk.getSQL()], config);180 }181 return this.buildQueryFromSourceParams([182 new StringChunk("("),183 chunk.getSQL(),184 new StringChunk(")")185 ], config);186 }187 if (inlineParams) {188 return { sql: this.mapInlineParam(chunk, config), params: [] };189 }190 return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };191 }));192 }193 mapInlineParam(chunk, { escapeString }) {194 if (chunk === null) {195 return "null";196 }197 if (typeof chunk === "number" || typeof chunk === "boolean") {198 return chunk.toString();199 }200 if (typeof chunk === "string") {201 return escapeString(chunk);202 }203 if (typeof chunk === "object") {204 const mappedValueAsString = chunk.toString();205 if (mappedValueAsString === "[object Object]") {206 return escapeString(JSON.stringify(chunk));207 }208 return escapeString(mappedValueAsString);209 }210 throw new Error("Unexpected param value: " + chunk);211 }212 getSQL() {213 return this;214 }215 as(alias) {216 if (alias === void 0) {217 return this;218 }219 return new SQL.Aliased(this, alias);220 }221 mapWith(decoder) {222 this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;223 return this;224 }225 inlineParams() {226 this.shouldInlineParams = true;227 return this;228 }229 /**230 * This method is used to conditionally include a part of the query.231 *232 * @param condition - Condition to check233 * @returns itself if the condition is `true`, otherwise `undefined`234 */235 if(condition) {236 return condition ? this : void 0;237 }238}239class Name {240 constructor(value) {241 this.value = value;242 }243 static [entityKind] = "Name";244 brand;245 getSQL() {246 return new SQL([this]);247 }248}249function name(value) {250 return new Name(value);251}252function isDriverValueEncoder(value) {253 return typeof value === "object" && value !== null && "mapToDriverValue" in value && typeof value.mapToDriverValue === "function";254}255const noopDecoder = {256 mapFromDriverValue: (value) => value257};258const noopEncoder = {259 mapToDriverValue: (value) => value260};261const noopMapper = {262 ...noopDecoder,263 ...noopEncoder264};265class Param {266 /**267 * @param value - Parameter value268 * @param encoder - Encoder to convert the value to a driver parameter269 */270 constructor(value, encoder = noopEncoder) {271 this.value = value;272 this.encoder = encoder;273 }274 static [entityKind] = "Param";275 brand;276 getSQL() {277 return new SQL([this]);278 }279}280function param(value, encoder) {281 return new Param(value, encoder);282}283function sql(strings, ...params) {284 const queryChunks = [];285 if (params.length > 0 || strings.length > 0 && strings[0] !== "") {286 queryChunks.push(new StringChunk(strings[0]));287 }288 for (const [paramIndex, param2] of params.entries()) {289 queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));290 }291 return new SQL(queryChunks);292}293((sql2) => {294 function empty() {295 return new SQL([]);296 }297 sql2.empty = empty;298 function fromList(list) {299 return new SQL(list);300 }301 sql2.fromList = fromList;302 function raw(str) {303 return new SQL([new StringChunk(str)]);304 }305 sql2.raw = raw;306 function join(chunks, separator) {307 const result = [];308 for (const [i, chunk] of chunks.entries()) {309 if (i > 0 && separator !== void 0) {310 result.push(separator);311 }312 result.push(chunk);313 }314 return new SQL(result);315 }316 sql2.join = join;317 function identifier(value) {318 return new Name(value);319 }320 sql2.identifier = identifier;321 function placeholder2(name2) {322 return new Placeholder(name2);323 }324 sql2.placeholder = placeholder2;325 function param2(value, encoder) {326 return new Param(value, encoder);327 }328 sql2.param = param2;329})(sql || (sql = {}));330((SQL2) => {331 class Aliased {332 constructor(sql2, fieldAlias) {333 this.sql = sql2;334 this.fieldAlias = fieldAlias;335 }336 static [entityKind] = "SQL.Aliased";337 /** @internal */338 isSelectionField = false;339 getSQL() {340 return this.sql;341 }342 /** @internal */343 clone() {344 return new Aliased(this.sql, this.fieldAlias);345 }346 }347 SQL2.Aliased = Aliased;348})(SQL || (SQL = {}));349class Placeholder {350 constructor(name2) {351 this.name = name2;352 }353 static [entityKind] = "Placeholder";354 getSQL() {355 return new SQL([this]);356 }357}358function placeholder(name2) {359 return new Placeholder(name2);360}361function fillPlaceholders(params, values) {362 return params.map((p) => {363 if (is(p, Placeholder)) {364 if (!(p.name in values)) {365 throw new Error(`No value for placeholder "${p.name}" was provided`);366 }367 return values[p.name];368 }369 if (is(p, Param) && is(p.value, Placeholder)) {370 if (!(p.value.name in values)) {371 throw new Error(`No value for placeholder "${p.value.name}" was provided`);372 }373 return p.encoder.mapToDriverValue(values[p.value.name]);374 }375 return p;376 });377}378const IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");379class View {380 static [entityKind] = "View";381 /** @internal */382 [ViewBaseConfig];383 /** @internal */384 [IsDrizzleView] = true;385 constructor({ name: name2, schema, selectedFields, query }) {386 this[ViewBaseConfig] = {387 name: name2,388 originalName: name2,389 schema,390 selectedFields,391 query,392 isExisting: !query,393 isAlias: false394 };395 }396 getSQL() {397 return new SQL([this]);398 }399}400function isView(view) {401 return typeof view === "object" && view !== null && IsDrizzleView in view;402}403function getViewName(view) {404 return view[ViewBaseConfig].name;405}406Column.prototype.getSQL = function() {407 return new SQL([this]);408};409Table.prototype.getSQL = function() {410 return new SQL([this]);411};412Subquery.prototype.getSQL = function() {413 return new SQL([this]);414};415export {416 FakePrimitiveParam,417 Name,418 Param,419 Placeholder,420 SQL,421 StringChunk,422 View,423 fillPlaceholders,424 getViewName,425 isDriverValueEncoder,426 isSQLWrapper,427 isView,428 name,429 noopDecoder,430 noopEncoder,431 noopMapper,432 param,433 placeholder,434 sql435};436//# sourceMappingURL=sql.js.map