@saltcorn/postgres 1.0.0-beta.9 → 1.0.0-rc.10

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.
Files changed (2) hide show
  1. package/package.json +4 -3
  2. package/postgres.js +32 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/postgres",
3
- "version": "1.0.0-beta.9",
3
+ "version": "1.0.0-rc.10",
4
4
  "description": "Postgres structures for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
6
  "scripts": {
@@ -12,9 +12,10 @@
12
12
  "license": "MIT",
13
13
  "main": "index.js",
14
14
  "dependencies": {
15
- "@saltcorn/db-common": "1.0.0-beta.9",
15
+ "@saltcorn/db-common": "1.0.0-rc.10",
16
16
  "pg": "^8.2.1",
17
- "pg-copy-streams": "^5.1.1"
17
+ "pg-copy-streams": "^5.1.1",
18
+ "replacestream": "4.0.3"
18
19
  },
19
20
  "repository": "github:saltcorn/saltcorn",
20
21
  "publishConfig": {
package/postgres.js CHANGED
@@ -9,7 +9,7 @@ const copyStreams = require("pg-copy-streams");
9
9
  const { promisify } = require("util");
10
10
  const { pipeline } = require("stream/promises");
11
11
  const { Transform } = require("stream");
12
-
12
+ const replace = require("replacestream");
13
13
  const {
14
14
  sqlsanitize,
15
15
  mkWhere,
@@ -64,7 +64,7 @@ const close = async () => {
64
64
  * @param {object} [connObj = {}] - connection object
65
65
  * @returns {Promise<void>}
66
66
  */
67
- const changeConnection = async (connObj = {}) => {
67
+ const changeConnection = async (connObj = Object.create(null)) => {
68
68
  await close();
69
69
  pool = new Pool(getConnectObject(connObj));
70
70
  };
@@ -93,7 +93,7 @@ const rollback = async () => {
93
93
  * @param {object} [selectopts = {}] - select options
94
94
  * @returns {Promise<*>} return rows
95
95
  */
96
- const select = async (tbl, whereObj, selectopts = {}) => {
96
+ const select = async (tbl, whereObj, selectopts = Object.create(null)) => {
97
97
  const { where, values } = mkWhere(whereObj);
98
98
  const schema = selectopts.schema || getTenantSchema();
99
99
  const sql = `SELECT ${
@@ -134,6 +134,28 @@ const drop_reset_schema = async (schema) => {
134
134
  */
135
135
  const count = async (tbl, whereObj) => {
136
136
  const { where, values } = mkWhere(whereObj);
137
+ if (!where) {
138
+ try {
139
+ // fast count for large table but may be stale
140
+ // https://stackoverflow.com/questions/7943233/fast-way-to-discover-the-row-count-of-a-table-in-postgresql
141
+ //https://www.citusdata.com/blog/2016/10/12/count-performance/
142
+ const sql = `SELECT (CASE WHEN c.reltuples < 0 THEN NULL
143
+ WHEN c.relpages = 0 THEN float8 '0' -- empty table
144
+ ELSE c.reltuples / c.relpages END
145
+ * (pg_catalog.pg_relation_size(c.oid)
146
+ / pg_catalog.current_setting('block_size')::int)
147
+ )::bigint
148
+ FROM pg_catalog.pg_class c
149
+ WHERE c.oid = '"${getTenantSchema()}"."${sqlsanitize(tbl)}"'::regclass`;
150
+ sql_log(sql);
151
+ const tq = await (client || pool).query(sql, []);
152
+ const n = +tq.rows[0].int8;
153
+ if (n && n > 10000) return n;
154
+ } catch {
155
+ //skip fast estimate
156
+ }
157
+ }
158
+
137
159
  const sql = `SELECT COUNT(*) FROM "${getTenantSchema()}"."${sqlsanitize(
138
160
  tbl
139
161
  )}" ${where}`;
@@ -167,7 +189,7 @@ const getVersion = async (short) => {
167
189
  * @param {object} [opts = {}]
168
190
  * @returns {Promise<object[]>} result of delete execution
169
191
  */
170
- const deleteWhere = async (tbl, whereObj, opts = {}) => {
192
+ const deleteWhere = async (tbl, whereObj, opts = Object.create(null)) => {
171
193
  const { where, values } = mkWhere(whereObj);
172
194
  const sql = `delete FROM "${getTenantSchema()}"."${sqlsanitize(
173
195
  tbl
@@ -186,7 +208,7 @@ const deleteWhere = async (tbl, whereObj, opts = {}) => {
186
208
  * @param {object} [opts = {}] - columns attributes
187
209
  * @returns {Promise<string>} returns primary key column or Id column value. If primary key column is not defined then return value of Id column.
188
210
  */
189
- const insert = async (tbl, obj, opts = {}) => {
211
+ const insert = async (tbl, obj, opts = Object.create(null)) => {
190
212
  const kvs = Object.entries(obj);
191
213
  const fnameList = kvs.map(([k, v]) => `"${sqlsanitize(k)}"`).join();
192
214
  var valPosList = [];
@@ -231,7 +253,7 @@ const insert = async (tbl, obj, opts = {}) => {
231
253
  * @param {object} [opts = {}] - columns attributes
232
254
  * @returns {Promise<void>} no result
233
255
  */
234
- const update = async (tbl, obj, id, opts = {}) => {
256
+ const update = async (tbl, obj, id, opts = Object.create(null)) => {
235
257
  const kvs = Object.entries(obj);
236
258
  if (kvs.length === 0) return;
237
259
  const assigns = kvs
@@ -256,7 +278,7 @@ const update = async (tbl, obj, id, opts = {}) => {
256
278
  * @param {object} opts - can contain a db client for transactions
257
279
  * @returns {Promise<void>} no result
258
280
  */
259
- const updateWhere = async (tbl, obj, whereObj, opts = {}) => {
281
+ const updateWhere = async (tbl, obj, whereObj, opts = Object.create(null)) => {
260
282
  const kvs = Object.entries(obj);
261
283
  if (kvs.length === 0) return;
262
284
  const { where, values } = mkWhere(whereObj, false, kvs.length);
@@ -280,7 +302,7 @@ const updateWhere = async (tbl, obj, whereObj, opts = {}) => {
280
302
  * @returns {Promise<object>} return first record from sql result
281
303
  * @throws {Error}
282
304
  */
283
- const selectOne = async (tbl, where, selectopts = {}) => {
305
+ const selectOne = async (tbl, where, selectopts = Object.create(null)) => {
284
306
  const rows = await select(tbl, where, { ...selectopts, limit: 1 });
285
307
  if (rows.length === 0) {
286
308
  const w = mkWhere(where);
@@ -295,7 +317,7 @@ const selectOne = async (tbl, where, selectopts = {}) => {
295
317
  * @param {object} [selectopts = {}] - select options
296
318
  * @returns {Promise<null|object>} - null if no record or first record data
297
319
  */
298
- const selectMaybeOne = async (tbl, where, selectopts = {}) => {
320
+ const selectMaybeOne = async (tbl, where, selectopts = Object.create(null)) => {
299
321
  const rows = await select(tbl, where, { ...selectopts, limit: 1 });
300
322
  if (rows.length === 0) return null;
301
323
  else return rows[0];
@@ -418,7 +440,7 @@ const copyToJson = async (fileStream, tableName, client) => {
418
440
  sql_log(sql);
419
441
  const stream = (client || pool).query(copyStreams.to(sql));
420
442
 
421
- return await pipeline(stream, fileStream);
443
+ return await pipeline(stream, replace("\\\\", "\\"), fileStream);
422
444
  };
423
445
 
424
446
  const slugify = (s) =>