prostgles-server 3.0.49 → 3.0.51

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 (47) hide show
  1. package/dist/DboBuilder/TableHandler.d.ts +3 -11
  2. package/dist/DboBuilder/TableHandler.d.ts.map +1 -1
  3. package/dist/DboBuilder/TableHandler.js +0 -74
  4. package/dist/DboBuilder/TableHandler.js.map +1 -1
  5. package/dist/DboBuilder/ViewHandler.d.ts +9 -1
  6. package/dist/DboBuilder/ViewHandler.d.ts.map +1 -1
  7. package/dist/DboBuilder/ViewHandler.js +127 -0
  8. package/dist/DboBuilder/ViewHandler.js.map +1 -1
  9. package/dist/DboBuilder/runSQL.d.ts.map +1 -1
  10. package/dist/DboBuilder/runSQL.js +23 -3
  11. package/dist/DboBuilder/runSQL.js.map +1 -1
  12. package/dist/DboBuilder.d.ts +10 -0
  13. package/dist/DboBuilder.d.ts.map +1 -1
  14. package/dist/DboBuilder.js.map +1 -1
  15. package/dist/Prostgles.d.ts.map +1 -1
  16. package/dist/Prostgles.js +10 -0
  17. package/dist/Prostgles.js.map +1 -1
  18. package/dist/PubSubManager.d.ts +10 -2
  19. package/dist/PubSubManager.d.ts.map +1 -1
  20. package/dist/PubSubManager.js +83 -75
  21. package/dist/PubSubManager.js.map +1 -1
  22. package/lib/DboBuilder/TableHandler.d.ts +1 -9
  23. package/lib/DboBuilder/TableHandler.d.ts.map +1 -1
  24. package/lib/DboBuilder/TableHandler.js +0 -74
  25. package/lib/DboBuilder/TableHandler.ts +2 -86
  26. package/lib/DboBuilder/ViewHandler.d.ts +9 -1
  27. package/lib/DboBuilder/ViewHandler.d.ts.map +1 -1
  28. package/lib/DboBuilder/ViewHandler.js +127 -0
  29. package/lib/DboBuilder/ViewHandler.ts +157 -2
  30. package/lib/DboBuilder/runSQL.d.ts.map +1 -1
  31. package/lib/DboBuilder/runSQL.js +23 -3
  32. package/lib/DboBuilder/runSQL.ts +24 -3
  33. package/lib/DboBuilder.d.ts +10 -0
  34. package/lib/DboBuilder.d.ts.map +1 -1
  35. package/lib/DboBuilder.ts +15 -2
  36. package/lib/Prostgles.d.ts.map +1 -1
  37. package/lib/Prostgles.js +10 -0
  38. package/lib/Prostgles.ts +11 -0
  39. package/lib/PubSubManager.d.ts +10 -2
  40. package/lib/PubSubManager.d.ts.map +1 -1
  41. package/lib/PubSubManager.js +83 -75
  42. package/lib/PubSubManager.ts +104 -82
  43. package/package.json +2 -2
  44. package/tests/client/PID.txt +1 -1
  45. package/tests/isomorphic_queries.js +2 -2
  46. package/tests/isomorphic_queries.ts +2 -2
  47. package/tests/server/package-lock.json +3 -3
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TableHandler = void 0;
4
4
  const prostgles_types_1 = require("prostgles-types");
5
5
  const DboBuilder_1 = require("../DboBuilder");
6
- const PubSubManager_1 = require("../PubSubManager");
7
6
  const delete_1 = require("./delete");
8
7
  const insert_1 = require("./insert");
9
8
  const insertDataParse_1 = require("./insertDataParse");
@@ -59,79 +58,6 @@ class TableHandler extends ViewHandler_1.ViewHandler {
59
58
  return true;
60
59
  }
61
60
  }
62
- async subscribe(filter, params = {}, localFunc, table_rules, localParams) {
63
- try {
64
- if (this.is_view)
65
- throw "Cannot subscribe to a view";
66
- if (this.t)
67
- throw "subscribe not allowed within transactions";
68
- if (!localParams && !localFunc)
69
- throw " missing data. provide -> localFunc | localParams { socket } ";
70
- if (localParams && localParams.socket && localFunc) {
71
- console.error({ localParams, localFunc });
72
- throw " Cannot have localFunc AND socket ";
73
- }
74
- const { filterFields, forcedFilter } = table_rules?.select || {}, filterOpts = await this.prepareWhere({ filter, forcedFilter, addKeywords: false, filterFields, tableAlias: undefined, localParams, tableRule: table_rules }), condition = filterOpts.where, throttle = params?.throttle || 0, selectParams = (0, PubSubManager_1.omitKeys)(params || {}, ["throttle"]);
75
- /** app_triggers condition field has an index which limits it's value */
76
- const filterSize = JSON.stringify(filter || {}).length;
77
- if (filterSize * 4 > 2704) {
78
- throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead";
79
- }
80
- if (!localFunc) {
81
- if (!this.dboBuilder.prostgles.isSuperUser)
82
- throw "Subscribe not possible. Must be superuser to add triggers 1856";
83
- return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
84
- .then(async (isValid) => {
85
- const { socket } = localParams ?? {};
86
- const pubSubManager = await this.dboBuilder.getPubSubManager();
87
- return pubSubManager.addSub({
88
- table_info: this.tableOrViewInfo,
89
- socket,
90
- table_rules,
91
- condition: condition,
92
- func: undefined,
93
- filter: { ...filter },
94
- params: { ...selectParams },
95
- socket_id: socket?.id,
96
- table_name: this.name,
97
- throttle,
98
- last_throttled: 0,
99
- }).then(channelName => ({ channelName }));
100
- });
101
- }
102
- else {
103
- const pubSubManager = await this.dboBuilder.getPubSubManager();
104
- pubSubManager.addSub({
105
- table_info: this.tableOrViewInfo,
106
- socket: undefined,
107
- table_rules,
108
- condition,
109
- func: localFunc,
110
- filter: { ...filter },
111
- params: { ...selectParams },
112
- socket_id: undefined,
113
- table_name: this.name,
114
- throttle,
115
- last_throttled: 0,
116
- }).then(channelName => ({ channelName }));
117
- const unsubscribe = async () => {
118
- const pubSubManager = await this.dboBuilder.getPubSubManager();
119
- pubSubManager.removeLocalSub(this.name, condition, localFunc);
120
- };
121
- let res = Object.freeze({ unsubscribe });
122
- return res;
123
- }
124
- }
125
- catch (e) {
126
- if (localParams && localParams.testRule)
127
- throw e;
128
- throw (0, DboBuilder_1.parseError)(e, `dbo.${this.name}.subscribe()`);
129
- }
130
- }
131
- subscribeOne(filter, params = {}, localFunc, table_rules, localParams) {
132
- let func = localParams ? undefined : (rows) => localFunc(rows[0]);
133
- return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
134
- }
135
61
  async updateBatch(data, params, tableRules, localParams) {
136
62
  try {
137
63
  const queries = await Promise.all(data.map(async ([filter, data]) => await this.update(filter, data, { ...(params || {}), returning: undefined }, tableRules, { ...(localParams || {}), returnQuery: true })));
@@ -1,9 +1,8 @@
1
1
  import pgPromise from "pg-promise";
2
- import { AnyObject, asName, DeleteParams, FieldFilter, getKeys, InsertParams, isDefined, isObject, Select, SelectParams, SubscribeParams, UpdateParams } from "prostgles-types";
2
+ import { AnyObject, asName, DeleteParams, FieldFilter, getKeys, InsertParams, isObject, Select, SelectParams, UpdateParams } from "prostgles-types";
3
3
  import { DboBuilder, Filter, LocalParams, makeErr, parseError, TableHandlers, TableSchema } from "../DboBuilder";
4
4
  import { DB } from "../Prostgles";
5
- import { SyncRule, TableRule, UpdateRule, ValidateRow, ValidateUpdateRow } from "../PublishParser";
6
- import { omitKeys } from "../PubSubManager";
5
+ import { SyncRule, TableRule } from "../PublishParser";
7
6
  import { _delete } from "./delete";
8
7
  import { insert } from "./insert";
9
8
  import { insertDataParse } from "./insertDataParse";
@@ -61,89 +60,6 @@ export class TableHandler extends ViewHandler {
61
60
  }
62
61
  }
63
62
 
64
- async subscribe(filter: Filter, params: SubscribeParams, localFunc: (items: AnyObject[]) => any): Promise<{ unsubscribe: () => any }>
65
- async subscribe(filter: Filter, params: SubscribeParams, localFunc?: (items: AnyObject[]) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>
66
- async subscribe(filter: Filter, params: SubscribeParams = {}, localFunc?: (items: AnyObject[]) => any, table_rules?: TableRule, localParams?: LocalParams):
67
- Promise<string | { unsubscribe: () => any }> {
68
- try {
69
- if (this.is_view) throw "Cannot subscribe to a view";
70
- if (this.t) throw "subscribe not allowed within transactions";
71
- if (!localParams && !localFunc) throw " missing data. provide -> localFunc | localParams { socket } ";
72
- if (localParams && localParams.socket && localFunc) {
73
- console.error({ localParams, localFunc })
74
- throw " Cannot have localFunc AND socket ";
75
- }
76
-
77
- const { filterFields, forcedFilter } = table_rules?.select || {},
78
- filterOpts = await this.prepareWhere({ filter, forcedFilter, addKeywords: false, filterFields, tableAlias: undefined, localParams, tableRule: table_rules }),
79
- condition = filterOpts.where,
80
- throttle = params?.throttle || 0,
81
- selectParams = omitKeys(params || {}, ["throttle"]);
82
-
83
- /** app_triggers condition field has an index which limits it's value */
84
- const filterSize = JSON.stringify(filter || {}).length;
85
- if (filterSize * 4 > 2704) {
86
- throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead"
87
- }
88
-
89
- if (!localFunc) {
90
- if (!this.dboBuilder.prostgles.isSuperUser) throw "Subscribe not possible. Must be superuser to add triggers 1856";
91
- return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
92
- .then(async isValid => {
93
-
94
- const { socket } = localParams ?? {};
95
- const pubSubManager = await this.dboBuilder.getPubSubManager();
96
- return pubSubManager.addSub({
97
- table_info: this.tableOrViewInfo,
98
- socket,
99
- table_rules,
100
- condition: condition,
101
- func: undefined,
102
- filter: { ...filter },
103
- params: { ...selectParams },
104
- socket_id: socket?.id,
105
- table_name: this.name,
106
- throttle,
107
- last_throttled: 0,
108
- }).then(channelName => ({ channelName }));
109
- }) as string;
110
- } else {
111
- const pubSubManager = await this.dboBuilder.getPubSubManager();
112
- pubSubManager.addSub({
113
- table_info: this.tableOrViewInfo,
114
- socket: undefined,
115
- table_rules,
116
- condition,
117
- func: localFunc,
118
- filter: { ...filter },
119
- params: { ...selectParams },
120
- socket_id: undefined,
121
- table_name: this.name,
122
- throttle,
123
- last_throttled: 0,
124
- }).then(channelName => ({ channelName }));
125
- const unsubscribe = async () => {
126
- const pubSubManager = await this.dboBuilder.getPubSubManager();
127
- pubSubManager.removeLocalSub(this.name, condition, localFunc)
128
- };
129
- let res: { unsubscribe: () => any } = Object.freeze({ unsubscribe })
130
- return res;
131
- }
132
- } catch (e) {
133
- if (localParams && localParams.testRule) throw e;
134
- throw parseError(e, `dbo.${this.name}.subscribe()`);
135
- }
136
- }
137
-
138
- /* This should only be called from server */
139
- subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any): Promise<{ unsubscribe: () => any }>
140
- subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>
141
- subscribeOne(filter: Filter, params: SubscribeParams = {}, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams):
142
- Promise<string | { unsubscribe: () => any }> {
143
- let func = localParams ? undefined : (rows: AnyObject[]) => localFunc(rows[0]);
144
- return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
145
- }
146
-
147
63
 
148
64
  async updateBatch(data: [Filter, AnyObject][], params?: UpdateParams, tableRules?: TableRule, localParams?: LocalParams): Promise<any> {
149
65
  try {
@@ -1,5 +1,5 @@
1
1
  import * as pgPromise from 'pg-promise';
2
- import { ColumnInfo, FieldFilter, SelectParams, OrderBy, TableInfo as TInfo, AnyObject } from "prostgles-types";
2
+ import { ColumnInfo, FieldFilter, SelectParams, OrderBy, TableInfo as TInfo, AnyObject, SubscribeParams } from "prostgles-types";
3
3
  import { DB, DBHandlerServer, Join } from "../Prostgles";
4
4
  import { DboBuilder, ExistsFilterConfig, Filter, JoinInfo, LocalParams, SortItem, TableHandlers, TableSchema, ValidatedTableRules } from "../DboBuilder";
5
5
  import { Graph } from "../shortestPath";
@@ -61,6 +61,14 @@ export declare class ViewHandler {
61
61
  getValidatedRules(tableRules?: TableRule, localParams?: LocalParams): ValidatedTableRules;
62
62
  find(filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, tableRules?: TableRule, localParams?: LocalParams): Promise<any[]>;
63
63
  findOne(filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<any>;
64
+ subscribe(filter: Filter, params: SubscribeParams, localFunc: (items: AnyObject[]) => any): Promise<{
65
+ unsubscribe: () => any;
66
+ }>;
67
+ subscribe(filter: Filter, params: SubscribeParams, localFunc?: (items: AnyObject[]) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>;
68
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any): Promise<{
69
+ unsubscribe: () => any;
70
+ }>;
71
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>;
64
72
  count(filter?: Filter, param2_unused?: undefined, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<number>;
65
73
  size(filter?: Filter, selectParams?: SelectParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<string>;
66
74
  getAllowedSelectFields(selectParams: FieldFilter, allowed_cols: FieldFilter, allow_empty?: boolean): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"ViewHandler.d.ts","sourceRoot":"","sources":["ViewHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ViewHandler.d.ts","sourceRoot":"","sources":["ViewHandler.ts"],"names":[],"mappings":"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"}
@@ -599,6 +599,133 @@ class ViewHandler {
599
599
  throw (0, DboBuilder_1.parseError)(e, `Issue with dbo.${this.name}.findOne()`);
600
600
  }
601
601
  }
602
+ async subscribe(filter, params = {}, localFunc, table_rules, localParams) {
603
+ try {
604
+ if (this.is_view)
605
+ throw "Cannot subscribe to a view";
606
+ if (this.t)
607
+ throw "subscribe not allowed within transactions";
608
+ if (!localParams && !localFunc)
609
+ throw " missing data. provide -> localFunc | localParams { socket } ";
610
+ if (localParams && localParams.socket && localFunc) {
611
+ console.error({ localParams, localFunc });
612
+ throw " Cannot have localFunc AND socket ";
613
+ }
614
+ const { filterFields, forcedFilter } = table_rules?.select || {}, filterOpts = await this.prepareWhere({ filter, forcedFilter, addKeywords: false, filterFields, tableAlias: undefined, localParams, tableRule: table_rules }), condition = filterOpts.where, throttle = params?.throttle || 0, selectParams = (0, PubSubManager_1.omitKeys)(params || {}, ["throttle"]);
615
+ /** app_triggers condition field has an index which limits it's value */
616
+ const filterSize = JSON.stringify(filter || {}).length;
617
+ if (filterSize * 4 > 2704) {
618
+ throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead";
619
+ }
620
+ if (!localFunc) {
621
+ if (!this.dboBuilder.prostgles.isSuperUser)
622
+ throw "Subscribe not possible. Must be superuser to add triggers 1856";
623
+ return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
624
+ .then(async (isValid) => {
625
+ let relatedTableSubscriptions = undefined;
626
+ if (this.is_view) {
627
+ const viewName = this.name;
628
+ const viewNameEscaped = this.escapedName;
629
+ /** Get list of used columns and their parent tables */
630
+ const { def } = await this.db.oneOrNone("SELECT pg_get_viewdef(${viewName}) as def", { viewName });
631
+ if (!def || typeof def !== "string")
632
+ (0, DboBuilder_1.makeErr)("Could get view definition");
633
+ const { fields } = await this.dboBuilder.dbo.sql(`SELECT * FROM ( \n ${def} \n ) prostgles_subscribe_view_definition LIMIT 0`, {});
634
+ const tableColumns = fields.filter(f => f.tableName && f.columnName);
635
+ /** Create exists filters for each table */
636
+ const tableIds = Array.from(new Set(tableColumns.map(tc => tc.tableID.toString())));
637
+ let relatedTableSubscriptions = tableIds.map(tableID => {
638
+ const table = this.dboBuilder.USER_TABLES?.find(t => t.relid === tableID);
639
+ let tableCols = tableColumns.filter(tc => tc.tableID.toString() === tableID);
640
+ /** If table has primary keys and they are all in this view then use only primary keys */
641
+ if (table?.pkey_columns?.every(pkey => tableCols.some(c => c.columnName === pkey))) {
642
+ tableCols = tableCols.filter(c => table?.pkey_columns?.includes(c.columnName));
643
+ }
644
+ else {
645
+ /** Exclude non comparable data types */
646
+ tableCols = tableCols.filter(c => ["json", "xml"].includes(c.udt_name));
647
+ }
648
+ const { tableName, tableSchema } = tableCols[0];
649
+ const tableNameEscaped = [tableSchema, tableName].map(v => (0, prostgles_types_1.asName)(v)).join(".");
650
+ const relatedTableSubscription = {
651
+ tableName,
652
+ tableNameEscaped,
653
+ condition: `EXISTS (
654
+ SELECT 1
655
+ FROM ${viewNameEscaped}
656
+ WHERE ${tableCols.map(c => `${tableNameEscaped}.${JSON.stringify(c.columnName)} = ${viewNameEscaped}.${JSON.stringify(c.name)}`).join(" AND \n")}
657
+ AND ${condition || "TRUE"}
658
+ )`
659
+ };
660
+ return relatedTableSubscription;
661
+ });
662
+ /** Get list of remaining used inner tables */
663
+ const allUsedTables = await this.db.any("SELECT distinct table_name, table_schema FROM information_schema.view_column_usage WHERE view_name = ${viewName}", { viewName });
664
+ /** Remaining tables will have listeners on all records (condition = "TRUE") */
665
+ const remainingInnerTables = allUsedTables.filter(at => !tableColumns.some(dc => dc.tableName === at.table_name && dc.tableSchema === at.table_schema));
666
+ relatedTableSubscriptions = [
667
+ ...relatedTableSubscriptions,
668
+ ...remainingInnerTables.map(t => ({
669
+ tableName: t.table_name,
670
+ tableNameEscaped: [t.table_name, t.table_schema].map(v => JSON.stringify(v)).join("."),
671
+ condition: ""
672
+ }))
673
+ ];
674
+ if (!relatedTableSubscriptions.length) {
675
+ throw "Could not subscribe to this view: no related tables found";
676
+ }
677
+ }
678
+ const { socket } = localParams ?? {};
679
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
680
+ return pubSubManager.addSub({
681
+ table_info: this.tableOrViewInfo,
682
+ socket,
683
+ table_rules,
684
+ table_name: this.name,
685
+ condition: condition,
686
+ relatedTableSubscriptions,
687
+ func: undefined,
688
+ filter: { ...filter },
689
+ params: { ...selectParams },
690
+ socket_id: socket?.id,
691
+ throttle,
692
+ last_throttled: 0,
693
+ }).then(channelName => ({ channelName }));
694
+ });
695
+ }
696
+ else {
697
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
698
+ pubSubManager.addSub({
699
+ table_info: this.tableOrViewInfo,
700
+ socket: undefined,
701
+ table_rules,
702
+ condition,
703
+ func: localFunc,
704
+ filter: { ...filter },
705
+ params: { ...selectParams },
706
+ socket_id: undefined,
707
+ table_name: this.name,
708
+ throttle,
709
+ last_throttled: 0,
710
+ }).then(channelName => ({ channelName }));
711
+ const unsubscribe = async () => {
712
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
713
+ pubSubManager.removeLocalSub(this.name, condition, localFunc);
714
+ };
715
+ let res = Object.freeze({ unsubscribe });
716
+ return res;
717
+ }
718
+ }
719
+ catch (e) {
720
+ if (localParams && localParams.testRule)
721
+ throw e;
722
+ throw (0, DboBuilder_1.parseError)(e, `dbo.${this.name}.subscribe()`);
723
+ }
724
+ }
725
+ subscribeOne(filter, params = {}, localFunc, table_rules, localParams) {
726
+ let func = localParams ? undefined : (rows) => localFunc(rows[0]);
727
+ return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
728
+ }
602
729
  async count(filter, param2_unused, param3_unused, table_rules, localParams) {
603
730
  filter = filter || {};
604
731
  try {
@@ -10,7 +10,7 @@ import {
10
10
  TableInfo as TInfo,
11
11
  AnyObject,
12
12
  isObject, isDefined, getKeys,
13
- _PG_geometric, pickKeys
13
+ _PG_geometric, pickKeys, SubscribeParams
14
14
  } from "prostgles-types";
15
15
  import { DB, DBHandlerServer, Join } from "../Prostgles";
16
16
  import {
@@ -20,7 +20,7 @@ import {
20
20
  } from "../DboBuilder";
21
21
  import { Graph } from "../shortestPath";
22
22
  import { TableRule, UpdateRule, ValidateRow } from "../PublishParser";
23
- import { asValue } from "../PubSubManager";
23
+ import { asValue, omitKeys } from "../PubSubManager";
24
24
  import { TableHandler } from "./TableHandler";
25
25
  import { asNameAlias, getNewQuery, parseFunctionObject, SelectItem, SelectItemValidated } from "./QueryBuilder/QueryBuilder";
26
26
  import { COMPUTED_FIELDS, FieldSpec, FUNCTIONS, parseFunction, } from "./QueryBuilder/Functions";
@@ -718,6 +718,161 @@ export class ViewHandler {
718
718
  }
719
719
  }
720
720
 
721
+
722
+
723
+ async subscribe(filter: Filter, params: SubscribeParams, localFunc: (items: AnyObject[]) => any): Promise<{ unsubscribe: () => any }>
724
+ async subscribe(filter: Filter, params: SubscribeParams, localFunc?: (items: AnyObject[]) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>
725
+ async subscribe(filter: Filter, params: SubscribeParams = {}, localFunc?: (items: AnyObject[]) => any, table_rules?: TableRule, localParams?: LocalParams):
726
+ Promise<string | { unsubscribe: () => any }> {
727
+ try {
728
+ if (this.is_view) throw "Cannot subscribe to a view";
729
+ if (this.t) throw "subscribe not allowed within transactions";
730
+ if (!localParams && !localFunc) throw " missing data. provide -> localFunc | localParams { socket } ";
731
+ if (localParams && localParams.socket && localFunc) {
732
+ console.error({ localParams, localFunc })
733
+ throw " Cannot have localFunc AND socket ";
734
+ }
735
+
736
+ const { filterFields, forcedFilter } = table_rules?.select || {},
737
+ filterOpts = await this.prepareWhere({ filter, forcedFilter, addKeywords: false, filterFields, tableAlias: undefined, localParams, tableRule: table_rules }),
738
+ condition = filterOpts.where,
739
+ throttle = params?.throttle || 0,
740
+ selectParams = omitKeys(params || {}, ["throttle"]);
741
+
742
+ /** app_triggers condition field has an index which limits it's value */
743
+ const filterSize = JSON.stringify(filter || {}).length;
744
+ if (filterSize * 4 > 2704) {
745
+ throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead"
746
+ }
747
+
748
+ if (!localFunc) {
749
+ if (!this.dboBuilder.prostgles.isSuperUser) throw "Subscribe not possible. Must be superuser to add triggers 1856";
750
+ return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
751
+ .then(async isValid => {
752
+
753
+ let relatedTableSubscriptions: {
754
+ tableName: string;
755
+ tableNameEscaped: string;
756
+ condition: string;
757
+ }[] | undefined = undefined;
758
+
759
+ if(this.is_view){
760
+ const viewName = this.name;
761
+ const viewNameEscaped = this.escapedName;
762
+
763
+ /** Get list of used columns and their parent tables */
764
+ const { def } = await this.db.oneOrNone("SELECT pg_get_viewdef(${viewName}) as def", { viewName });
765
+ if(!def || typeof def !== "string") makeErr("Could get view definition");
766
+ const { fields } = await this.dboBuilder.dbo.sql!(`SELECT * FROM ( \n ${def} \n ) prostgles_subscribe_view_definition LIMIT 0`, {});
767
+ const tableColumns = fields.filter(f => f.tableName && f.columnName);
768
+
769
+ /** Create exists filters for each table */
770
+ const tableIds = Array.from(new Set(tableColumns.map(tc => tc.tableID!.toString())));
771
+ let relatedTableSubscriptions = tableIds.map(tableID => {
772
+ const table = this.dboBuilder.USER_TABLES?.find(t => t.relid === tableID)!;
773
+ let tableCols = tableColumns.filter(tc => tc.tableID!.toString() === tableID);
774
+
775
+ /** If table has primary keys and they are all in this view then use only primary keys */
776
+ if(table?.pkey_columns?.every(pkey => tableCols.some(c => c.columnName === pkey))){
777
+ tableCols = tableCols.filter(c => table?.pkey_columns?.includes(c.columnName!))
778
+ } else {
779
+ /** Exclude non comparable data types */
780
+ tableCols = tableCols.filter(c => ["json", "xml"].includes(c.udt_name) )
781
+ }
782
+
783
+ const { tableName, tableSchema } = tableCols[0]!;
784
+ const tableNameEscaped = [tableSchema!, tableName!].map(v => asName(v)).join(".");
785
+
786
+ const relatedTableSubscription = {
787
+ tableName,
788
+ tableNameEscaped,
789
+ condition: `EXISTS (
790
+ SELECT 1
791
+ FROM ${viewNameEscaped}
792
+ WHERE ${tableCols.map(c => `${tableNameEscaped}.${JSON.stringify(c.columnName)} = ${viewNameEscaped}.${JSON.stringify(c.name)}`).join(" AND \n")}
793
+ AND ${condition || "TRUE"}
794
+ )`
795
+ }
796
+
797
+ return relatedTableSubscription;
798
+ })
799
+
800
+ /** Get list of remaining used inner tables */
801
+ const allUsedTables: { table_name: string; table_schema: string; }[] = await this.db.any(
802
+ "SELECT distinct table_name, table_schema FROM information_schema.view_column_usage WHERE view_name = ${viewName}",
803
+ { viewName }
804
+ );
805
+
806
+ /** Remaining tables will have listeners on all records (condition = "TRUE") */
807
+ const remainingInnerTables = allUsedTables.filter(at => !tableColumns.some(dc => dc.tableName === at.table_name && dc.tableSchema === at.table_schema));
808
+ relatedTableSubscriptions = [
809
+ ...relatedTableSubscriptions,
810
+ ...remainingInnerTables.map(t => ({
811
+ tableName: t.table_name,
812
+ tableNameEscaped: [t.table_name, t.table_schema].map(v => JSON.stringify(v)).join("."),
813
+ condition: ""
814
+ }))
815
+ ];
816
+
817
+ if(!relatedTableSubscriptions.length){
818
+ throw "Could not subscribe to this view: no related tables found";
819
+ }
820
+ }
821
+
822
+ const { socket } = localParams ?? {};
823
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
824
+ return pubSubManager.addSub({
825
+ table_info: this.tableOrViewInfo,
826
+ socket,
827
+ table_rules,
828
+ table_name: this.name,
829
+ condition: condition,
830
+ relatedTableSubscriptions,
831
+ func: undefined,
832
+ filter: { ...filter },
833
+ params: { ...selectParams },
834
+ socket_id: socket?.id,
835
+ throttle,
836
+ last_throttled: 0,
837
+ }).then(channelName => ({ channelName }));
838
+ }) as string;
839
+ } else {
840
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
841
+ pubSubManager.addSub({
842
+ table_info: this.tableOrViewInfo,
843
+ socket: undefined,
844
+ table_rules,
845
+ condition,
846
+ func: localFunc,
847
+ filter: { ...filter },
848
+ params: { ...selectParams },
849
+ socket_id: undefined,
850
+ table_name: this.name,
851
+ throttle,
852
+ last_throttled: 0,
853
+ }).then(channelName => ({ channelName }));
854
+ const unsubscribe = async () => {
855
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
856
+ pubSubManager.removeLocalSub(this.name, condition, localFunc)
857
+ };
858
+ let res: { unsubscribe: () => any } = Object.freeze({ unsubscribe })
859
+ return res;
860
+ }
861
+ } catch (e) {
862
+ if (localParams && localParams.testRule) throw e;
863
+ throw parseError(e, `dbo.${this.name}.subscribe()`);
864
+ }
865
+ }
866
+
867
+ /* This should only be called from server */
868
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any): Promise<{ unsubscribe: () => any }>
869
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>
870
+ subscribeOne(filter: Filter, params: SubscribeParams = {}, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams):
871
+ Promise<string | { unsubscribe: () => any }> {
872
+ let func = localParams ? undefined : (rows: AnyObject[]) => localFunc(rows[0]);
873
+ return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
874
+ }
875
+
721
876
  async count(filter?: Filter, param2_unused?: undefined, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<number> {
722
877
  filter = filter || {};
723
878
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"runSQL.d.ts","sourceRoot":"","sources":["runSQL.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK7C,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,WAAW,gBAkGpI;AAED,eAAO,MAAM,SAAS,cAAqB,SAAS,gBAAgB,WAAW,KAAG,QAAQ,OAAO,CAOhG,CAAA;AAED,eAAO,MAAM,eAAe,cAAmB,QAAQ,OAAO,CAE7D,CAAA"}
1
+ {"version":3,"file":"runSQL.d.ts","sourceRoot":"","sources":["runSQL.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK7C,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,WAAW,gBAuHpI;AAED,eAAO,MAAM,SAAS,cAAqB,SAAS,gBAAgB,WAAW,KAAG,QAAQ,OAAO,CAOhG,CAAA;AAED,eAAO,MAAM,eAAe,cAAmB,QAAQ,OAAO,CAE7D,CAAA"}
@@ -14,7 +14,25 @@ async function runSQL(query, params, options, localParams) {
14
14
  }
15
15
  /** Cache types */
16
16
  this.DATA_TYPES ?? (this.DATA_TYPES = await this.db.any("SELECT oid, typname FROM pg_type") ?? []);
17
- this.USER_TABLES ?? (this.USER_TABLES = await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables") ?? []);
17
+ this.USER_TABLES ?? (this.USER_TABLES = await this.db.any(`
18
+ SELECT relid, relname, schemaname, array_to_json(array_agg(c.column_name) FILTER (WHERE c.column_name IS NOT NULL))
19
+ FROM pg_catalog.pg_statio_user_tables t
20
+ LEFT JOIN (
21
+ SELECT a.attname as column_name, i.indrelid as table_oid
22
+ FROM pg_index i
23
+ JOIN pg_attribute a ON a.attrelid = i.indrelid
24
+ AND a.attnum = ANY(i.indkey)
25
+ WHERE i.indisprimary
26
+ ) c
27
+ ON t.relid = c.table_oid
28
+ GROUP BY relid, relname, schemaname
29
+ `) ?? []);
30
+ this.USER_TABLE_COLUMNS ?? (this.USER_TABLE_COLUMNS = await this.db.any(`
31
+ SELECT t.relid, t.schemaname,t.relname, c.column_name, c.udt_name
32
+ FROM information_schema.columns c
33
+ INNER JOIN pg_catalog.pg_statio_user_tables t
34
+ ON c.table_schema = t.schemaname AND c.table_name = t.relname
35
+ `));
18
36
  if (!(await (0, exports.canRunSQL)(this.prostgles, localParams)))
19
37
  throw "Not allowed to run SQL";
20
38
  const { returnType, allowListen, hasParams = true } = options || {};
@@ -80,13 +98,15 @@ async function runSQL(query, params, options, localParams) {
80
98
  duration: 0,
81
99
  ..._qres,
82
100
  fields: fields?.map(f => {
83
- const dataType = this.DATA_TYPES.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text", tableName = this.USER_TABLES.find(t => +t.relid === +f.tableID), tsDataType = (0, DboBuilder_1.postgresToTsType)(dataType);
101
+ const dataType = this.DATA_TYPES.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text", table = this.USER_TABLES.find(t => +t.relid === +f.tableID), column = this.USER_TABLE_COLUMNS.find(c => +c.relid === +f.tableID && c.ordinal_position === f.columnID), tsDataType = (0, DboBuilder_1.postgresToTsType)(dataType);
84
102
  return {
85
103
  ...f,
86
104
  tsDataType,
87
105
  dataType,
88
106
  udt_name: dataType,
89
- tableName: tableName?.relname
107
+ tableName: table?.relname,
108
+ tableSchema: table?.schemaname,
109
+ columnName: column?.column_name
90
110
  };
91
111
  }) ?? []
92
112
  };
@@ -17,7 +17,25 @@ export async function runSQL(this: DboBuilder, query: string, params: any, optio
17
17
 
18
18
  /** Cache types */
19
19
  this.DATA_TYPES ??= await this.db.any("SELECT oid, typname FROM pg_type") ?? [];
20
- this.USER_TABLES ??= await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables") ?? [];
20
+ this.USER_TABLES ??= await this.db.any(`
21
+ SELECT relid, relname, schemaname, array_to_json(array_agg(c.column_name) FILTER (WHERE c.column_name IS NOT NULL))
22
+ FROM pg_catalog.pg_statio_user_tables t
23
+ LEFT JOIN (
24
+ SELECT a.attname as column_name, i.indrelid as table_oid
25
+ FROM pg_index i
26
+ JOIN pg_attribute a ON a.attrelid = i.indrelid
27
+ AND a.attnum = ANY(i.indkey)
28
+ WHERE i.indisprimary
29
+ ) c
30
+ ON t.relid = c.table_oid
31
+ GROUP BY relid, relname, schemaname
32
+ `) ?? [];
33
+ this.USER_TABLE_COLUMNS ??= await this.db.any(`
34
+ SELECT t.relid, t.schemaname,t.relname, c.column_name, c.udt_name
35
+ FROM information_schema.columns c
36
+ INNER JOIN pg_catalog.pg_statio_user_tables t
37
+ ON c.table_schema = t.schemaname AND c.table_name = t.relname
38
+ `);
21
39
 
22
40
  if (!(await canRunSQL(this.prostgles, localParams))) throw "Not allowed to run SQL";
23
41
 
@@ -87,7 +105,8 @@ export async function runSQL(this: DboBuilder, query: string, params: any, optio
87
105
  ..._qres,
88
106
  fields: fields?.map(f => {
89
107
  const dataType = this.DATA_TYPES!.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text",
90
- tableName = this.USER_TABLES!.find(t => +t.relid === +f.tableID),
108
+ table = this.USER_TABLES!.find(t => +t.relid === +f.tableID),
109
+ column = this.USER_TABLE_COLUMNS!.find(c => +c.relid === +f.tableID && c.ordinal_position === f.columnID),
91
110
  tsDataType = postgresToTsType(dataType);
92
111
 
93
112
  return {
@@ -95,7 +114,9 @@ export async function runSQL(this: DboBuilder, query: string, params: any, optio
95
114
  tsDataType,
96
115
  dataType,
97
116
  udt_name: dataType,
98
- tableName: tableName?.relname
117
+ tableName: table?.relname,
118
+ tableSchema: table?.schemaname,
119
+ columnName: column?.column_name
99
120
  }
100
121
  }) ?? []
101
122
  };