{"version":3,"file":"mysql-connection.mjs","sources":["../../../src/mysql-connection.ts"],"sourcesContent":["import mysql from 'mysql2/promise';\nimport {RdbmsConnection} from '@shopify/shopify-app-session-storage';\n\nexport class MySqlConnection implements RdbmsConnection {\n  sessionStorageIdentifier: string;\n  private ready: Promise<void>;\n  private dbUrl: URL;\n  private connectionPoolLimit: number;\n  private pool: mysql.Pool;\n\n  constructor(\n    dbUrl: URL,\n    sessionStorageIdentifier: string,\n    connectionPoolLimit: number,\n  ) {\n    this.dbUrl = dbUrl;\n    this.connectionPoolLimit = connectionPoolLimit;\n    this.ready = this.init();\n    this.sessionStorageIdentifier = sessionStorageIdentifier;\n  }\n\n  async query(query: string, params: any[] = []): Promise<any[]> {\n    await this.ready;\n    return this.pool.query(query, params);\n  }\n\n  /**\n   * Runs a series of queries in a transaction.\n   *\n   * @param queries an array of SQL queries to execute in a transaction\n   */\n  async transaction(queries: string[]): Promise<void> {\n    await this.ready;\n\n    // check if the first and last queries are BEGIN and COMMIT, if they are, ignore them\n    // mysql2\n    if (queries[0] === 'BEGIN') {\n      queries.shift();\n    }\n    if (queries[queries.length - 1] === 'COMMIT') {\n      queries.pop();\n    }\n    const client = await this.pool.getConnection();\n    try {\n      await client.beginTransaction();\n      for (const query of queries) {\n        await client.query(query);\n      }\n      await client.commit();\n    } catch (error) {\n      // rollback if any of the queries fail\n      await client.rollback();\n      throw error;\n    } finally {\n      client.release();\n    }\n  }\n\n  async connect(): Promise<void> {\n    await this.ready;\n\n    // Nothing else to do here\n    return Promise.resolve();\n  }\n\n  async disconnect(): Promise<void> {\n    await this.ready;\n    await this.pool.end();\n    this.ready = this.init();\n  }\n\n  getDatabase(): string | undefined {\n    return decodeURIComponent(this.dbUrl.pathname.slice(1));\n  }\n\n  async hasTable(tablename: string): Promise<boolean> {\n    await this.ready;\n\n    const query = `\n      SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES\n        WHERE TABLE_NAME = ${this.getArgumentPlaceholder()}\n          AND TABLE_SCHEMA = ${this.getArgumentPlaceholder()};\n    `;\n\n    // Allow multiple apps to be on the same host with separate DB and querying the right\n    // DB for the session table existence\n    const [rows] = await this.pool.query(query, [\n      tablename,\n      this.getDatabase(),\n    ]);\n    return Array.isArray(rows) && rows.length === 1;\n  }\n\n  getArgumentPlaceholder(_?: number): string {\n    return `?`;\n  }\n\n  private async init(): Promise<void> {\n    this.pool = await mysql.createPool({\n      connectionLimit: this.connectionPoolLimit,\n      host: this.dbUrl.hostname,\n      user: decodeURIComponent(this.dbUrl.username),\n      password: decodeURIComponent(this.dbUrl.password),\n      database: this.getDatabase(),\n      port: Number(this.dbUrl.port),\n    });\n  }\n}\n"],"names":[],"mappings":"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"}