session.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { NoopCache } from "../cache/core/index.js";
  2. import { Column } from "../column.js";
  3. import { entityKind, is } from "../entity.js";
  4. import { NoopLogger } from "../logger.js";
  5. import {
  6. MySqlPreparedQuery,
  7. MySqlSession,
  8. MySqlTransaction
  9. } from "../mysql-core/session.js";
  10. import { fillPlaceholders, sql } from "../sql/sql.js";
  11. import { mapResultRow } from "../utils.js";
  12. class PlanetScalePreparedQuery extends MySqlPreparedQuery {
  13. constructor(client, queryString, params, logger, cache, queryMetadata, cacheConfig, fields, customResultMapper, generatedIds, returningIds) {
  14. super(cache, queryMetadata, cacheConfig);
  15. this.client = client;
  16. this.queryString = queryString;
  17. this.params = params;
  18. this.logger = logger;
  19. this.fields = fields;
  20. this.customResultMapper = customResultMapper;
  21. this.generatedIds = generatedIds;
  22. this.returningIds = returningIds;
  23. }
  24. static [entityKind] = "PlanetScalePreparedQuery";
  25. rawQuery = { as: "object" };
  26. query = { as: "array" };
  27. async execute(placeholderValues = {}) {
  28. const params = fillPlaceholders(this.params, placeholderValues);
  29. this.logger.logQuery(this.queryString, params);
  30. const {
  31. fields,
  32. client,
  33. queryString,
  34. rawQuery,
  35. query,
  36. joinsNotNullableMap,
  37. customResultMapper,
  38. returningIds,
  39. generatedIds
  40. } = this;
  41. if (!fields && !customResultMapper) {
  42. const res = await this.queryWithCache(queryString, params, async () => {
  43. return await client.execute(queryString, params, rawQuery);
  44. });
  45. const insertId = Number.parseFloat(res.insertId);
  46. const affectedRows = res.rowsAffected;
  47. if (returningIds) {
  48. const returningResponse = [];
  49. let j = 0;
  50. for (let i = insertId; i < insertId + affectedRows; i++) {
  51. for (const column of returningIds) {
  52. const key = returningIds[0].path[0];
  53. if (is(column.field, Column)) {
  54. if (column.field.primary && column.field.autoIncrement) {
  55. returningResponse.push({ [key]: i });
  56. }
  57. if (column.field.defaultFn && generatedIds) {
  58. returningResponse.push({ [key]: generatedIds[j][key] });
  59. }
  60. }
  61. }
  62. j++;
  63. }
  64. return returningResponse;
  65. }
  66. return res;
  67. }
  68. const { rows } = await this.queryWithCache(queryString, params, async () => {
  69. return await client.execute(queryString, params, query);
  70. });
  71. if (customResultMapper) {
  72. return customResultMapper(rows);
  73. }
  74. return rows.map((row) => mapResultRow(fields, row, joinsNotNullableMap));
  75. }
  76. iterator(_placeholderValues) {
  77. throw new Error("Streaming is not supported by the PlanetScale Serverless driver");
  78. }
  79. }
  80. class PlanetscaleSession extends MySqlSession {
  81. constructor(baseClient, dialect, tx, schema, options = {}) {
  82. super(dialect);
  83. this.baseClient = baseClient;
  84. this.schema = schema;
  85. this.options = options;
  86. this.client = tx ?? baseClient;
  87. this.logger = options.logger ?? new NoopLogger();
  88. this.cache = options.cache ?? new NoopCache();
  89. }
  90. static [entityKind] = "PlanetscaleSession";
  91. logger;
  92. client;
  93. cache;
  94. prepareQuery(query, fields, customResultMapper, generatedIds, returningIds, queryMetadata, cacheConfig) {
  95. return new PlanetScalePreparedQuery(
  96. this.client,
  97. query.sql,
  98. query.params,
  99. this.logger,
  100. this.cache,
  101. queryMetadata,
  102. cacheConfig,
  103. fields,
  104. customResultMapper,
  105. generatedIds,
  106. returningIds
  107. );
  108. }
  109. async query(query, params) {
  110. this.logger.logQuery(query, params);
  111. return await this.client.execute(query, params, { as: "array" });
  112. }
  113. async queryObjects(query, params) {
  114. return this.client.execute(query, params, { as: "object" });
  115. }
  116. all(query) {
  117. const querySql = this.dialect.sqlToQuery(query);
  118. this.logger.logQuery(querySql.sql, querySql.params);
  119. return this.client.execute(querySql.sql, querySql.params, { as: "object" }).then((eQuery) => eQuery.rows);
  120. }
  121. async count(sql2) {
  122. const res = await this.execute(sql2);
  123. return Number(
  124. res["rows"][0]["count"]
  125. );
  126. }
  127. transaction(transaction) {
  128. return this.baseClient.transaction((pstx) => {
  129. const session = new PlanetscaleSession(this.baseClient, this.dialect, pstx, this.schema, this.options);
  130. const tx = new PlanetScaleTransaction(
  131. this.dialect,
  132. session,
  133. this.schema
  134. );
  135. return transaction(tx);
  136. });
  137. }
  138. }
  139. class PlanetScaleTransaction extends MySqlTransaction {
  140. static [entityKind] = "PlanetScaleTransaction";
  141. constructor(dialect, session, schema, nestedIndex = 0) {
  142. super(dialect, session, schema, nestedIndex, "planetscale");
  143. }
  144. async transaction(transaction) {
  145. const savepointName = `sp${this.nestedIndex + 1}`;
  146. const tx = new PlanetScaleTransaction(
  147. this.dialect,
  148. this.session,
  149. this.schema,
  150. this.nestedIndex + 1
  151. );
  152. await tx.execute(sql.raw(`savepoint ${savepointName}`));
  153. try {
  154. const result = await transaction(tx);
  155. await tx.execute(sql.raw(`release savepoint ${savepointName}`));
  156. return result;
  157. } catch (err) {
  158. await tx.execute(sql.raw(`rollback to savepoint ${savepointName}`));
  159. throw err;
  160. }
  161. }
  162. }
  163. export {
  164. PlanetScalePreparedQuery,
  165. PlanetScaleTransaction,
  166. PlanetscaleSession
  167. };
  168. //# sourceMappingURL=session.js.map