@saltcorn/postgres 1.0.0-beta.9 → 1.0.0-rc.2
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.
- package/package.json +4 -3
- 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-
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
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-
|
|
15
|
+
"@saltcorn/db-common": "1.0.0-rc.2",
|
|
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) =>
|