UNPKG

@langchain/community

Version:
1 lines • 34.7 kB
{"version":3,"file":"mariadb.cjs","names":["VectorStore","embeddings: EmbeddingsInterface","config: MariaDBStoreArgs","identifier: string","alwaysQuote: boolean","definition: string","config: MariaDBStoreArgs & { dimensions?: number }","texts: string[]","metadatas: object[] | object","dbConfig: MariaDBStoreArgs & { dimensions?: number }","Document","docs: Document[]","documents: Document[]","options?: { ids?: string[] }","vectors: number[][]","vector: number[]","params: {\n ids?: string[];\n filter?: Record<string, unknown>;\n }","params","filter?: Record<string, unknown>","_filter: Record<string, unknown>","parameters: any[]","filter: Record<string, unknown>","groupOperator: string","_value: Record<string, any>","query: number[]","k: number","parameters: unknown[]"],"sources":["../../src/vectorstores/mariadb.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport mariadb, { type Pool, type PoolConfig } from \"mariadb\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\n\ntype Metadata = Record<string, unknown>;\n\nexport type DistanceStrategy = \"COSINE\" | \"EUCLIDEAN\";\n\nconst STANDARD_SIMPLE_OPERATOR = new Map<string, string>([\n [\"$eq\", \"=\"],\n [\"$ne\", \"!=\"],\n [\"$lt\", \"<\"],\n [\"$lte\", \"<=\"],\n [\"$gt\", \">\"],\n [\"$gte\", \">=\"],\n]);\n\nconst STANDARD_LIST_OPERATOR = new Map<string, string>([\n [\"$in\", \"in\"],\n [\"$nin\", \"not in\"],\n]);\n\nconst STANDARD_BETWEEN_OPERATOR = new Map<string, string>([\n [\"$like\", \"like\"],\n [\"$nlike\", \"no like\"],\n]);\n\nconst GROUP_OPERATORS = new Map<string, string>([\n [\"$or\", \"or\"],\n [\"$and\", \"and\"],\n [\"$not\", \"not\"],\n]);\n\nconst SUPPORTED_OPERATORS = new Map<string, string>([\n ...STANDARD_SIMPLE_OPERATOR,\n ...STANDARD_LIST_OPERATOR,\n ...STANDARD_BETWEEN_OPERATOR,\n ...GROUP_OPERATORS,\n]);\n\n/**\n * Interface that defines the arguments required to create a\n * `MariaDBStore` instance. It includes MariaDB connection options,\n * table name and verbosity level.\n */\nexport interface MariaDBStoreArgs {\n connectionOptions?: PoolConfig;\n pool?: Pool;\n tableName?: string;\n collectionTableName?: string;\n collectionName?: string;\n collectionMetadata?: Metadata | null;\n schemaName?: string | null;\n columns?: {\n idColumnName?: string;\n vectorColumnName?: string;\n contentColumnName?: string;\n metadataColumnName?: string;\n };\n verbose?: boolean;\n /**\n * The amount of documents to chunk by when\n * adding vectors.\n * @default 500\n */\n chunkSize?: number;\n ids?: string[];\n distanceStrategy?: DistanceStrategy;\n}\n\n/**\n * MariaDB vector store integration.\n *\n * Setup:\n * Install `@langchain/community` and `mariadb`.\n *\n * If you wish to generate ids, you should also install the `uuid` package.\n *\n * ```bash\n * npm install @langchain/community mariadb uuid\n * ```\n *\n * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.vectorstores_mariadb.MariaDB.html#constructor)\n *\n * <details open>\n * <summary><strong>Instantiate</strong></summary>\n *\n * ```typescript\n * import {\n * MariaDBStore,\n * DistanceStrategy,\n * } from \"@langchain/community/vectorstores/mariadb\";\n *\n * // Or other embeddings\n * import { OpenAIEmbeddings } from \"@langchain/openai\";\n * import { PoolConfig } from \"mariadb\";\n *\n * const embeddings = new OpenAIEmbeddings({\n * model: \"text-embedding-3-small\",\n * });\n *\n * // Sample config\n * const config = {\n * connectionOptions: {\n * host: \"127.0.0.1\",\n * port: 3306,\n * user: \"myuser\",\n * password: \"ChangeMe\",\n * database: \"api\",\n * } as PoolConfig,\n * tableName: \"testlangchainjs\",\n * columns: {\n * idColumnName: \"id\",\n * vectorColumnName: \"vector\",\n * contentColumnName: \"content\",\n * metadataColumnName: \"metadata\",\n * },\n * // supported distance strategies: COSINE (default) or EUCLIDEAN\n * distanceStrategy: \"COSINE\" as DistanceStrategy,\n * };\n *\n * const vectorStore = await MariaDBStore.initialize(embeddings, config);\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Add documents</strong></summary>\n *\n * ```typescript\n * import type { Document } from '@langchain/core/documents';\n *\n * const document1 = { pageContent: \"foo\", metadata: { baz: \"bar\" } };\n * const document2 = { pageContent: \"thud\", metadata: { bar: \"baz\" } };\n * const document3 = { pageContent: \"i will be deleted :(\", metadata: {} };\n *\n * const documents: Document[] = [document1, document2, document3];\n * const ids = [\"1\", \"2\", \"3\"];\n * await vectorStore.addDocuments(documents, { ids });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Delete documents</strong></summary>\n *\n * ```typescript\n * await vectorStore.delete({ ids: [\"3\"] });\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>Similarity search</strong></summary>\n *\n * ```typescript\n * const results = await vectorStore.similaritySearch(\"thud\", 1);\n * for (const doc of results) {\n * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * thud [{\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n *\n * <details>\n * <summary><strong>Similarity search with filter</strong></summary>\n *\n * ```typescript\n * const resultsWithFilter = await vectorStore.similaritySearch(\"thud\", 1, {\"country\": \"BG\"});\n *\n * for (const doc of resultsWithFilter) {\n * console.log(`* ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * foo [{\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n *\n * <details>\n * <summary><strong>Similarity search with score</strong></summary>\n *\n * ```typescript\n * const resultsWithScore = await vectorStore.similaritySearchWithScore(\"qux\", 1);\n * for (const [doc, score] of resultsWithScore) {\n * console.log(`* [SIM=${score.toFixed(6)}] ${doc.pageContent} [${JSON.stringify(doc.metadata, null)}]`);\n * }\n * // Output: * [SIM=0.000000] qux [{\"bar\":\"baz\",\"baz\":\"bar\"}]\n * ```\n * </details>\n *\n * <br />\n *\n * <details>\n * <summary><strong>As a retriever</strong></summary>\n *\n * ```typescript\n * const retriever = vectorStore.asRetriever({\n * searchType: \"mmr\", // Leave blank for standard similarity search\n * k: 1,\n * });\n * const resultAsRetriever = await retriever.invoke(\"thud\");\n * console.log(resultAsRetriever);\n *\n * // Output: [Document({ metadata: { \"baz\":\"bar\" }, pageContent: \"thud\" })]\n * ```\n * </details>\n *\n * <br />\n */\nexport class MariaDBStore extends VectorStore {\n tableName: string;\n\n collectionTableName?: string;\n\n collectionName = \"langchain\";\n\n collectionId?: string;\n\n collectionMetadata: Metadata | null;\n\n schemaName: string | null;\n\n idColumnName: string;\n\n vectorColumnName: string;\n\n contentColumnName: string;\n\n metadataColumnName: string;\n\n _verbose?: boolean;\n\n pool: Pool;\n\n chunkSize = 500;\n\n distanceStrategy: DistanceStrategy;\n\n constructor(embeddings: EmbeddingsInterface, config: MariaDBStoreArgs) {\n super(embeddings, config);\n this.tableName = this.escapeId(config.tableName ?? \"langchain\", false);\n if (\n config.collectionName !== undefined &&\n config.collectionTableName === undefined\n ) {\n throw new Error(\n `If supplying a \"collectionName\", you must also supply a \"collectionTableName\".`\n );\n }\n\n this.collectionTableName = config.collectionTableName\n ? this.escapeId(config.collectionTableName, false)\n : undefined;\n\n this.collectionName = config.collectionName\n ? this.escapeId(config.collectionName, false)\n : \"langchaincol\";\n\n this.collectionMetadata = config.collectionMetadata ?? null;\n this.schemaName = config.schemaName\n ? this.escapeId(config.schemaName, false)\n : null;\n\n this.vectorColumnName = this.escapeId(\n config.columns?.vectorColumnName ?? \"embedding\",\n false\n );\n this.contentColumnName = this.escapeId(\n config.columns?.contentColumnName ?? \"text\",\n false\n );\n this.idColumnName = this.escapeId(\n config.columns?.idColumnName ?? \"id\",\n false\n );\n this.metadataColumnName = this.escapeId(\n config.columns?.metadataColumnName ?? \"metadata\",\n false\n );\n\n if (!config.connectionOptions && !config.pool) {\n throw new Error(\n \"You must provide either a `connectionOptions` object or a `pool` instance.\"\n );\n }\n\n const langchainVerbose = getEnvironmentVariable(\"LANGCHAIN_VERBOSE\");\n\n if (langchainVerbose === \"true\") {\n this._verbose = true;\n } else if (langchainVerbose === \"false\") {\n this._verbose = false;\n } else {\n this._verbose = config.verbose;\n }\n\n if (config.pool) {\n this.pool = config.pool;\n } else {\n const poolConf = { ...config.connectionOptions, rowsAsArray: true };\n // add query to log if verbose\n if (this._verbose) poolConf.logger = { query: console.log };\n this.pool = mariadb.createPool(poolConf);\n }\n this.chunkSize = config.chunkSize ?? 500;\n\n this.distanceStrategy =\n config.distanceStrategy ?? (\"COSINE\" as DistanceStrategy);\n }\n\n get computedTableName() {\n return this.schemaName == null\n ? this.tableName\n : `${this.schemaName}.${this.tableName}`;\n }\n\n get computedCollectionTableName() {\n return this.schemaName == null\n ? `${this.collectionTableName}`\n : `\"${this.schemaName}\".\"${this.collectionTableName}\"`;\n }\n\n /**\n * Escape identifier\n *\n * @param identifier identifier value\n * @param alwaysQuote must identifier be quoted if not required\n */\n private escapeId(identifier: string, alwaysQuote: boolean): string {\n if (!identifier || identifier === \"\")\n throw new Error(\"Identifier is required\");\n\n const len = identifier.length;\n const simpleIdentifier = /^[0-9a-zA-Z$_]*$/;\n if (simpleIdentifier.test(identifier)) {\n if (len < 1 || len > 64) {\n throw new Error(\"Invalid identifier length\");\n }\n if (alwaysQuote) return `\\`${identifier}\\``;\n\n // Identifier names may begin with a numeral, but can't only contain numerals unless quoted.\n if (/^\\d+$/.test(identifier)) {\n // identifier containing only numerals must be quoted\n return `\\`${identifier}\\``;\n }\n // identifier containing only numerals must be quoted\n return identifier;\n } else {\n if (identifier.includes(\"\\u0000\")) {\n throw new Error(\"Invalid name - containing u0000 character\");\n }\n let ident = identifier;\n if (/^`.+`$/.test(identifier)) {\n ident = identifier.substring(1, identifier.length - 1);\n }\n if (len < 1 || len > 64) {\n throw new Error(\"Invalid identifier length\");\n }\n return `\\`${ident.replace(/`/g, \"``\")}\\``;\n }\n }\n\n private printable(definition: string): string {\n return definition.replaceAll(/[^0-9a-zA-Z_]/g, \"\");\n }\n\n /**\n * Static method to create a new `MariaDBStore` instance from a\n * connection. It creates a table if one does not exist, and calls\n * `connect` to return a new instance of `MariaDBStore`.\n *\n * @param embeddings - Embeddings instance.\n * @param fields - `MariaDBStoreArgs` instance\n * @param fields.dimensions Number of dimensions in your vector data type. default to 1536.\n * @returns A new instance of `MariaDBStore`.\n */\n static async initialize(\n embeddings: EmbeddingsInterface,\n config: MariaDBStoreArgs & { dimensions?: number }\n ): Promise<MariaDBStore> {\n const { dimensions, ...rest } = config;\n const mariadbStore = new MariaDBStore(embeddings, rest);\n await mariadbStore.ensureTableInDatabase(dimensions);\n await mariadbStore.ensureCollectionTableInDatabase();\n await mariadbStore.loadCollectionId();\n\n return mariadbStore;\n }\n\n /**\n * Static method to create a new `MariaDBStore` instance from an\n * array of texts and their metadata. It converts the texts into\n * `Document` instances and adds them to the store.\n *\n * @param texts - Array of texts.\n * @param metadatas - Array of metadata objects or a single metadata object.\n * @param embeddings - Embeddings instance.\n * @param dbConfig - `MariaDBStoreArgs` instance.\n * @returns Promise that resolves with a new instance of `MariaDBStore`.\n */\n static async fromTexts(\n texts: string[],\n metadatas: object[] | object,\n embeddings: EmbeddingsInterface,\n dbConfig: MariaDBStoreArgs & { dimensions?: number }\n ): Promise<MariaDBStore> {\n const docs = [];\n for (let i = 0; i < texts.length; i += 1) {\n const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;\n const newDoc = new Document({\n pageContent: texts[i],\n metadata,\n });\n docs.push(newDoc);\n }\n\n return MariaDBStore.fromDocuments(docs, embeddings, dbConfig);\n }\n\n /**\n * Static method to create a new `MariaDBStore` instance from an\n * array of `Document` instances. It adds the documents to the store.\n *\n * @param docs - Array of `Document` instances.\n * @param embeddings - Embeddings instance.\n * @param dbConfig - `MariaDBStoreArgs` instance.\n * @returns Promise that resolves with a new instance of `MariaDBStore`.\n */\n static async fromDocuments(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig: MariaDBStoreArgs & { dimensions?: number }\n ): Promise<MariaDBStore> {\n const instance = await MariaDBStore.initialize(embeddings, dbConfig);\n await instance.addDocuments(docs, { ids: dbConfig.ids });\n return instance;\n }\n\n _vectorstoreType(): string {\n return \"mariadb\";\n }\n\n /**\n * Method to add documents to the vector store. It converts the documents into\n * vectors, and adds them to the store.\n *\n * @param documents - Array of `Document` instances.\n * @param options - Optional arguments for adding documents\n * @returns Promise that resolves when the documents have been added.\n */\n async addDocuments(\n documents: Document[],\n options?: { ids?: string[] }\n ): Promise<void> {\n const texts = documents.map(({ pageContent }) => pageContent);\n\n return this.addVectors(\n await this.embeddings.embedDocuments(texts),\n documents,\n options\n );\n }\n\n /**\n * Inserts a row for the collectionName provided at initialization if it does not\n * exist and set the collectionId.\n */\n private async loadCollectionId(): Promise<void> {\n if (this.collectionId) {\n return;\n }\n\n if (this.collectionTableName) {\n const queryResult = await this.pool.query(\n {\n sql: `SELECT uuid from ${this.computedCollectionTableName} WHERE label = ?`,\n rowsAsArray: true,\n },\n [this.collectionName]\n );\n if (queryResult.length > 0) {\n this.collectionId = queryResult[0][0];\n } else {\n const insertString = `INSERT INTO ${this.computedCollectionTableName}(label, cmetadata) VALUES (?, ?) RETURNING uuid`;\n const insertResult = await this.pool.query(\n { sql: insertString, rowsAsArray: true },\n [this.collectionName, this.collectionMetadata]\n );\n this.collectionId = insertResult[0][0];\n }\n }\n }\n\n /**\n * Method to add vectors to the vector store. It converts the vectors into\n * rows and inserts them into the database.\n *\n * @param vectors - Array of vectors.\n * @param documents - Array of `Document` instances.\n * @param options - Optional arguments for adding documents\n * @returns Promise that resolves when the vectors have been added.\n */\n async addVectors(\n vectors: number[][],\n documents: Document[],\n options?: { ids?: string[] }\n ): Promise<void> {\n const ids = options?.ids;\n\n // Either all documents have ids or none of them do to avoid confusion.\n if (ids !== undefined && ids.length !== vectors.length) {\n throw new Error(\n \"The number of ids must match the number of vectors provided.\"\n );\n }\n await this.loadCollectionId();\n\n const insertQuery = `INSERT INTO ${this.computedTableName}(${\n this.idColumnName\n },${this.contentColumnName},${this.metadataColumnName},${\n this.vectorColumnName\n }${this.collectionId ? \",collection_id\" : \"\"}) VALUES (${\n ids ? \"?\" : \"UUID_v7()\"\n }, ?, ?, ?${this.collectionId ? \", ?\" : \"\"})`;\n\n try {\n const batchParams = [];\n for (let i = 0; i < vectors.length; i += 1) {\n const param = [\n ids ? ids[i] : null,\n documents[i].pageContent,\n documents[i].metadata,\n this.getFloat32Buffer(vectors[i]),\n this.collectionId,\n ];\n if (!ids) param.shift();\n if (!this.collectionId) param.pop();\n batchParams.push(param);\n }\n await this.pool.batch(insertQuery, batchParams);\n } catch (e) {\n console.error(e);\n throw new Error(`Error inserting: ${(e as Error).message}`);\n }\n }\n\n /**\n * Convert float array to binary value\n * @param vector embedding value\n * @private\n */\n private getFloat32Buffer(vector: number[]) {\n return Buffer.from(new Float32Array(vector).buffer);\n }\n\n /**\n * Method to delete documents from the vector store. It deletes the\n * documents that match the provided ids\n *\n * @param ids - array of ids\n * @returns Promise that resolves when the documents have been deleted.\n * @example\n * await vectorStore.delete([\"id1\", \"id2\"]);\n */\n async delete(params: {\n ids?: string[];\n filter?: Record<string, unknown>;\n }): Promise<void> {\n const { ids, filter } = params;\n\n if (!(ids || filter)) {\n throw new Error(\n \"You must specify either ids or a filter when deleting documents.\"\n );\n }\n await this.loadCollectionId();\n\n if (ids) {\n // delete by ids\n await this.pool.query(\n `DELETE FROM ${this.computedTableName} WHERE ${\n this.idColumnName\n } IN (?) ${this.collectionId ? \" AND collection_id = ?\" : \"\"}`,\n [ids, this.collectionId]\n );\n } else if (filter) {\n // delete by filter\n const [filterPart, params] = this.filterConverter(filter);\n if (filterPart.length === 0) throw new Error(\"Wrong filter.\");\n await this.pool.query(\n `DELETE FROM ${this.computedTableName} WHERE ${filterPart} ${\n this.collectionId ? \" AND collection_id = ?\" : \"\"\n }`,\n [...params, this.collectionId]\n );\n }\n }\n\n private filterConverter(filter?: Record<string, unknown>): [string, any[]] {\n if (!filter) return [\"\", []];\n const _filter: Record<string, unknown> = filter ?? {};\n const parameters: any[] = [];\n let sqlFilter = this.subFilterConverter(_filter, parameters, \"$and\");\n if (sqlFilter.charAt(0) === \"(\") {\n sqlFilter = sqlFilter.substring(1, sqlFilter.length - 1);\n }\n return [sqlFilter, parameters];\n }\n\n private subFilterConverter(\n filter: Record<string, unknown>,\n parameters: any[],\n groupOperator: string\n ): string {\n const sqlFilterPart = [];\n\n for (const [key, value] of Object.entries(filter)) {\n if (typeof value === \"object\" && value !== null) {\n const _value: Record<string, any> = value;\n for (const [type, subvalue] of Object.entries(_value)) {\n let realvalue = subvalue;\n if (STANDARD_LIST_OPERATOR.has(type)) {\n if (!Array.isArray(realvalue)) {\n if (\n typeof realvalue !== \"string\" ||\n typeof realvalue !== \"number\"\n ) {\n throw new Error(\n \"value for in/not in filter are expected to be an array type\"\n );\n }\n realvalue = [realvalue];\n }\n\n const placeholders = realvalue.map(() => \"?\").join(\",\");\n sqlFilterPart.push(\n `JSON_VALUE(${\n this.metadataColumnName\n }, '$.${key}') ${STANDARD_LIST_OPERATOR.get(\n type\n )} (${placeholders})`\n );\n parameters.push(...realvalue);\n } else if (GROUP_OPERATORS.has(type)) {\n sqlFilterPart.push(\n this.subFilterConverter(realvalue, parameters, type)\n );\n } else if (SUPPORTED_OPERATORS.has(type)) {\n sqlFilterPart.push(\n `JSON_VALUE(${\n this.metadataColumnName\n }, '$.${key}') ${SUPPORTED_OPERATORS.get(type)} ?`\n );\n parameters.push(realvalue);\n } else {\n throw new Error(\n `unknown type operation, must be in ${SUPPORTED_OPERATORS.keys()}`\n );\n }\n }\n } else {\n sqlFilterPart.push(\n `JSON_VALUE(${this.metadataColumnName}, '$.${key}') = ?`\n );\n parameters.push(value);\n }\n }\n if (sqlFilterPart.length > 1) {\n return `(${sqlFilterPart.join(\n ` ${GROUP_OPERATORS.get(groupOperator)} `\n )})`;\n } else {\n return sqlFilterPart[0];\n }\n }\n\n /**\n * Method to perform a similarity search in the vector store. It returns\n * the `k` most similar documents to the query vector, along with their\n * similarity scores.\n *\n * @param query - Query vector.\n * @param k - Number of most similar documents to return.\n * @param filter - Optional filter to apply to the search.\n * @returns Promise that resolves with an array of tuples, each containing a `Document` and its similarity score.\n */\n async similaritySearchVectorWithScore(\n query: number[],\n k: number,\n filter?: Record<string, unknown>\n ): Promise<[Document, number][]> {\n const parameters: unknown[] = [this.getFloat32Buffer(query)];\n const whereClauses = [];\n\n await this.loadCollectionId();\n\n if (this.collectionId) {\n whereClauses.push(\"collection_id = ?\");\n parameters.push(this.collectionId);\n }\n\n if (filter) {\n const [filterPart, params] = this.filterConverter(filter);\n whereClauses.push(filterPart);\n parameters.push(...params);\n }\n\n // limit\n parameters.push(k);\n\n const whereClause = whereClauses.length\n ? `WHERE ${whereClauses.join(\" AND \")}`\n : \"\";\n\n const queryString = `SELECT ${this.idColumnName},${this.contentColumnName},${this.metadataColumnName},VEC_DISTANCE_${this.distanceStrategy}(${this.vectorColumnName}, ?) as distance FROM ${this.computedTableName} ${whereClause} ORDER BY distance ASC LIMIT ?`;\n\n const documents = await this.pool.execute(\n { sql: queryString, rowsAsArray: true },\n parameters\n );\n\n const results = [] as [Document, number][];\n for (const doc of documents) {\n if (doc[3] != null && doc[1] != null) {\n const document = new Document({\n id: doc[0],\n pageContent: doc[1],\n metadata: doc[2],\n });\n results.push([document, doc[3]]);\n }\n }\n return results;\n }\n\n /**\n * Method to ensure the existence of the table in the database. It creates\n * the table if it does not already exist.\n * @param dimensions Number of dimensions in your vector data type. Default to 1536.\n * @returns Promise that resolves when the table has been ensured.\n */\n async ensureTableInDatabase(dimensions = 1536): Promise<void> {\n const tableQuery = `CREATE TABLE IF NOT EXISTS ${this.computedTableName}(${\n this.idColumnName\n } UUID NOT NULL DEFAULT UUID_v7() PRIMARY KEY,${\n this.contentColumnName\n } TEXT,${this.metadataColumnName} JSON,${\n this.vectorColumnName\n } VECTOR(${dimensions}) NOT NULL, VECTOR INDEX ${this.printable(\n `${this.tableName}_${this.vectorColumnName}`\n )}_idx (${this.vectorColumnName}) ) ENGINE=InnoDB`;\n await this.pool.query(tableQuery);\n }\n\n /**\n * Method to ensure the existence of the collection table in the database.\n * It creates the table if it does not already exist.\n *\n * @returns Promise that resolves when the collection table has been ensured.\n */\n async ensureCollectionTableInDatabase(): Promise<void> {\n try {\n if (this.collectionTableName != null) {\n await Promise.all([\n this.pool.query(\n `CREATE TABLE IF NOT EXISTS ${\n this.computedCollectionTableName\n }(uuid UUID NOT NULL DEFAULT UUID_v7() PRIMARY KEY,\n label VARCHAR(256), cmetadata JSON, UNIQUE KEY idx_${this.printable(\n this.collectionTableName\n )}_label\n (label))`\n ),\n this.pool.query(\n `ALTER TABLE ${this.computedTableName}\n ADD COLUMN IF NOT EXISTS collection_id uuid,\n ADD CONSTRAINT FOREIGN KEY IF NOT EXISTS ${this.printable(\n this.tableName\n )}_collection_id_fkey (collection_id)\n REFERENCES ${\n this.computedCollectionTableName\n }(uuid) ON DELETE CASCADE`\n ),\n ]);\n }\n } catch (e) {\n console.error(e);\n throw new Error(\n `Error adding column or creating index: ${(e as Error).message}`\n );\n }\n }\n\n /**\n * Close the pool.\n *\n * @returns Promise that resolves when the pool is terminated.\n */\n async end(): Promise<void> {\n return this.pool.end();\n }\n}\n"],"mappings":"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"}