prostgles-server 3.0.64 → 3.0.66

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 (123) hide show
  1. package/dist/AuthHandler.d.ts +11 -11
  2. package/dist/AuthHandler.d.ts.map +1 -1
  3. package/dist/DBSchemaBuilder.d.ts +3 -3
  4. package/dist/DBSchemaBuilder.d.ts.map +1 -1
  5. package/dist/DboBuilder/QueryBuilder/Functions.d.ts +3 -3
  6. package/dist/DboBuilder/QueryBuilder/Functions.d.ts.map +1 -1
  7. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +3 -3
  8. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
  9. package/dist/DboBuilder/TableHandler.d.ts +1 -1
  10. package/dist/DboBuilder/TableHandler.d.ts.map +1 -1
  11. package/dist/DboBuilder/ViewHandler.d.ts +5 -4
  12. package/dist/DboBuilder/ViewHandler.d.ts.map +1 -1
  13. package/dist/DboBuilder/ViewHandler.js +7 -134
  14. package/dist/DboBuilder/ViewHandler.js.map +1 -1
  15. package/dist/DboBuilder/delete.js +1 -1
  16. package/dist/DboBuilder/delete.js.map +1 -1
  17. package/dist/DboBuilder/insert.js +1 -1
  18. package/dist/DboBuilder/insert.js.map +1 -1
  19. package/dist/DboBuilder/insertDataParse.js +1 -1
  20. package/dist/DboBuilder/insertDataParse.js.map +1 -1
  21. package/dist/DboBuilder/runSQL.js +1 -1
  22. package/dist/DboBuilder/runSQL.js.map +1 -1
  23. package/dist/DboBuilder/subscribe.d.ts +11 -0
  24. package/dist/DboBuilder/subscribe.d.ts.map +1 -0
  25. package/dist/DboBuilder/subscribe.js +190 -0
  26. package/dist/DboBuilder/subscribe.js.map +1 -0
  27. package/dist/DboBuilder/update.js +1 -1
  28. package/dist/DboBuilder/update.js.map +1 -1
  29. package/dist/DboBuilder.d.ts +24 -24
  30. package/dist/DboBuilder.d.ts.map +1 -1
  31. package/dist/DboBuilder.js +1 -1
  32. package/dist/DboBuilder.js.map +1 -1
  33. package/dist/FileManager.d.ts +6 -6
  34. package/dist/FileManager.d.ts.map +1 -1
  35. package/dist/FileManager.js +17 -17
  36. package/dist/FileManager.js.map +1 -1
  37. package/dist/Filtering.d.ts +1 -1
  38. package/dist/Filtering.d.ts.map +1 -1
  39. package/dist/PostgresNotifListenManager.d.ts +1 -1
  40. package/dist/PostgresNotifListenManager.d.ts.map +1 -1
  41. package/dist/Prostgles.d.ts +14 -14
  42. package/dist/Prostgles.d.ts.map +1 -1
  43. package/dist/Prostgles.js +12 -12
  44. package/dist/Prostgles.js.map +1 -1
  45. package/{lib → dist/PubSubManager}/PubSubManager.d.ts +24 -19
  46. package/dist/PubSubManager/PubSubManager.d.ts.map +1 -0
  47. package/dist/PubSubManager/PubSubManager.js +770 -0
  48. package/dist/PubSubManager/PubSubManager.js.map +1 -0
  49. package/dist/PubSubManager/initPubSubManager.d.ts +3 -0
  50. package/dist/PubSubManager/initPubSubManager.d.ts.map +1 -0
  51. package/dist/PubSubManager/initPubSubManager.js +616 -0
  52. package/dist/PubSubManager/initPubSubManager.js.map +1 -0
  53. package/dist/PublishParser.d.ts +32 -32
  54. package/dist/PublishParser.d.ts.map +1 -1
  55. package/dist/PublishParser.js +1 -1
  56. package/dist/PublishParser.js.map +1 -1
  57. package/dist/SchemaWatch.d.ts +1 -1
  58. package/dist/SchemaWatch.d.ts.map +1 -1
  59. package/dist/SyncReplication.d.ts +6 -6
  60. package/dist/SyncReplication.d.ts.map +1 -1
  61. package/dist/SyncReplication.js +1 -1
  62. package/dist/SyncReplication.js.map +1 -1
  63. package/dist/TableConfig.d.ts +21 -21
  64. package/dist/TableConfig.d.ts.map +1 -1
  65. package/dist/TableConfig.js +13 -13
  66. package/dist/TableConfig.js.map +1 -1
  67. package/dist/shortestPath.d.ts +1 -1
  68. package/dist/shortestPath.d.ts.map +1 -1
  69. package/dist/validation.d.ts +9 -9
  70. package/dist/validation.d.ts.map +1 -1
  71. package/dist/validation.js +1 -1
  72. package/dist/validation.js.map +1 -1
  73. package/lib/DboBuilder/ViewHandler.d.ts +4 -3
  74. package/lib/DboBuilder/ViewHandler.d.ts.map +1 -1
  75. package/lib/DboBuilder/ViewHandler.js +7 -134
  76. package/lib/DboBuilder/ViewHandler.ts +15 -164
  77. package/lib/DboBuilder/delete.js +1 -1
  78. package/lib/DboBuilder/delete.ts +1 -1
  79. package/lib/DboBuilder/insert.js +1 -1
  80. package/lib/DboBuilder/insert.ts +1 -1
  81. package/lib/DboBuilder/insertDataParse.js +1 -1
  82. package/lib/DboBuilder/insertDataParse.ts +1 -1
  83. package/lib/DboBuilder/runSQL.js +1 -1
  84. package/lib/DboBuilder/runSQL.ts +1 -1
  85. package/lib/DboBuilder/subscribe.d.ts +11 -0
  86. package/lib/DboBuilder/subscribe.d.ts.map +1 -0
  87. package/lib/DboBuilder/subscribe.js +189 -0
  88. package/lib/DboBuilder/subscribe.ts +230 -0
  89. package/lib/DboBuilder/update.js +1 -1
  90. package/lib/DboBuilder/update.ts +1 -1
  91. package/lib/DboBuilder.d.ts +1 -1
  92. package/lib/DboBuilder.d.ts.map +1 -1
  93. package/lib/DboBuilder.js +1 -1
  94. package/lib/DboBuilder.ts +1 -1
  95. package/lib/Prostgles.js +1 -1
  96. package/lib/Prostgles.ts +1 -1
  97. package/{dist → lib/PubSubManager}/PubSubManager.d.ts +19 -14
  98. package/lib/PubSubManager/PubSubManager.d.ts.map +1 -0
  99. package/lib/PubSubManager/PubSubManager.js +792 -0
  100. package/lib/PubSubManager/PubSubManager.ts +1016 -0
  101. package/lib/PubSubManager/initPubSubManager.d.ts +3 -0
  102. package/lib/PubSubManager/initPubSubManager.d.ts.map +1 -0
  103. package/lib/PubSubManager/initPubSubManager.js +615 -0
  104. package/lib/PubSubManager/initPubSubManager.ts +630 -0
  105. package/lib/PublishParser.js +1 -1
  106. package/lib/PublishParser.ts +1 -1
  107. package/lib/SyncReplication.d.ts +1 -1
  108. package/lib/SyncReplication.d.ts.map +1 -1
  109. package/lib/SyncReplication.js +1 -1
  110. package/lib/SyncReplication.ts +1 -1
  111. package/lib/TableConfig.js +1 -1
  112. package/lib/TableConfig.ts +1 -1
  113. package/lib/validation.js +1 -1
  114. package/lib/validation.ts +1 -1
  115. package/package.json +5 -4
  116. package/tests/client/PID.txt +1 -1
  117. package/tests/server/package-lock.json +7 -5
  118. package/dist/PubSubManager.d.ts.map +0 -1
  119. package/dist/PubSubManager.js +0 -1398
  120. package/dist/PubSubManager.js.map +0 -1
  121. package/lib/PubSubManager.d.ts.map +0 -1
  122. package/lib/PubSubManager.js +0 -1420
  123. package/lib/PubSubManager.ts +0 -1655
@@ -20,13 +20,13 @@ import {
20
20
  } from "../DboBuilder";
21
21
  import { Graph } from "../shortestPath";
22
22
  import { TableRule, UpdateRule, ValidateRow } from "../PublishParser";
23
- import { asValue, omitKeys } from "../PubSubManager";
23
+ import { asValue, omitKeys } from "../PubSubManager/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";
27
27
  import { parseFilterItem } from "../Filtering";
28
28
  import { getColumns } from "./getColumns";
29
-
29
+ import { LocalFunc, subscribe } from "./subscribe";
30
30
  export type JoinPaths = {
31
31
  t1: string;
32
32
  t2: string;
@@ -718,173 +718,24 @@ 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
-
730
- if (this.t) throw "subscribe not allowed within transactions";
731
- if (!localParams && !localFunc) throw " missing data. provide -> localFunc | localParams { socket } ";
732
- if (localParams && localParams.socket && localFunc) {
733
- console.error({ localParams, localFunc })
734
- throw " Cannot have localFunc AND socket ";
735
- }
736
-
737
- const { filterFields, forcedFilter } = table_rules?.select || {},
738
- filterOpts = await this.prepareWhere({ filter, forcedFilter, addKeywords: false, filterFields, tableAlias: undefined, localParams, tableRule: table_rules }),
739
- condition = filterOpts.where,
740
- throttle = params?.throttle || 0,
741
- selectParams = omitKeys(params || {}, ["throttle"]);
742
-
743
- /** app_triggers condition field has an index which limits it's value */
744
- const filterSize = JSON.stringify(filter || {}).length;
745
- if (filterSize * 4 > 2704) {
746
- throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead"
747
- }
748
-
749
- if (!localFunc) {
750
- if (!this.dboBuilder.prostgles.isSuperUser) throw "Subscribe not possible. Must be superuser to add triggers 1856";
751
- return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
752
- .then(async isValid => {
753
-
754
- let relatedTableSubscriptions: {
755
- tableName: string;
756
- tableNameEscaped: string;
757
- condition: string;
758
- }[] | undefined = undefined;
759
-
760
- if(this.is_view){
761
- const viewName = this.name;
762
- const viewNameEscaped = this.escapedName;
763
- const { current_schema } = await this.db.oneOrNone("SELECT current_schema")
764
-
765
- /** Get list of used columns and their parent tables */
766
- let { def } = (await this.db.oneOrNone("SELECT pg_get_viewdef(${viewName}) as def", { viewName })) as { def: string };
767
- def = def.trim();
768
- if(def.endsWith(";")) {
769
- def = def.slice(0, -1);
770
- }
771
- if(!def || typeof def !== "string") makeErr("Could get view definition");
772
- const { fields } = await this.dboBuilder.dbo.sql!(`SELECT * FROM ( \n ${def} \n ) prostgles_subscribe_view_definition LIMIT 0`, {});
773
- const tableColumns = fields.filter(f => f.tableName && f.columnName);
774
-
775
- /** Create exists filters for each table */
776
- const tableIds = Array.from(new Set(tableColumns.map(tc => tc.tableID!.toString())));
777
- relatedTableSubscriptions = tableIds.map(tableID => {
778
- const table = this.dboBuilder.USER_TABLES?.find(t => t.relid === +tableID)!;
779
- let tableCols = tableColumns.filter(tc => tc.tableID!.toString() === tableID);
780
-
781
- /** If table has primary keys and they are all in this view then use only primary keys */
782
- if(table?.pkey_columns?.every(pkey => tableCols.some(c => c.columnName === pkey))){
783
- tableCols = tableCols.filter(c => table?.pkey_columns?.includes(c.columnName!))
784
- } else {
785
- /** Exclude non comparable data types */
786
- tableCols = tableCols.filter(c => !["json", "xml"].includes(c.udt_name) )
787
- }
788
-
789
- const { relname: tableName, schemaname: tableSchema } = table;
790
- if(!tableCols.length){
791
- return {
792
- tableName: tableName,
793
- tableNameEscaped: JSON.stringify(tableName),// [table.schemaname, table.relname].map(v => JSON.stringify(v)).join("."),
794
- condition: "TRUE"
795
- }
796
- }
797
-
798
- const tableNameEscaped = tableSchema === current_schema? table.relname : [tableSchema, tableName].map(v => JSON.stringify(v)).join(".");
799
-
800
- const relatedTableSubscription = {
801
- tableName: tableName!,
802
- tableNameEscaped,
803
- condition: `EXISTS (
804
- SELECT 1
805
- FROM ${viewNameEscaped}
806
- WHERE ${tableCols.map(c => `${tableNameEscaped}.${JSON.stringify(c.columnName)} = ${viewNameEscaped}.${JSON.stringify(c.name)}`).join(" AND \n")}
807
- AND ${condition || "TRUE"}
808
- )`
809
- }
810
-
811
- return relatedTableSubscription;
812
- })
813
-
814
- /** Get list of remaining used inner tables */
815
- const allUsedTables: { table_name: string; table_schema: string; }[] = await this.db.any(
816
- "SELECT distinct table_name, table_schema FROM information_schema.view_column_usage WHERE view_name = ${viewName}",
817
- { viewName }
818
- );
819
-
820
- /** Remaining tables will have listeners on all records (condition = "TRUE") */
821
- const remainingInnerTables = allUsedTables.filter(at => !tableColumns.some(dc => dc.tableName === at.table_name && dc.tableSchema === at.table_schema));
822
- relatedTableSubscriptions = [
823
- ...relatedTableSubscriptions,
824
- ...remainingInnerTables.map(t => ({
825
- tableName: t.table_name,
826
- tableNameEscaped: [t.table_name, t.table_schema].map(v => JSON.stringify(v)).join("."),
827
- condition: "TRUE"
828
- }))
829
- ];
830
-
831
- if(!relatedTableSubscriptions.length){
832
- throw "Could not subscribe to this view: no related tables found";
833
- }
834
- }
835
-
836
- const { socket } = localParams ?? {};
837
- const pubSubManager = await this.dboBuilder.getPubSubManager();
838
- return pubSubManager.addSub({
839
- table_info: this.tableOrViewInfo,
840
- socket,
841
- table_rules,
842
- table_name: this.name,
843
- condition: condition,
844
- relatedTableSubscriptions,
845
- func: undefined,
846
- filter: { ...filter },
847
- params: { ...selectParams },
848
- socket_id: socket?.id,
849
- throttle,
850
- last_throttled: 0,
851
- }).then(channelName => ({ channelName }));
852
- }) as string;
853
- } else {
854
- const pubSubManager = await this.dboBuilder.getPubSubManager();
855
- pubSubManager.addSub({
856
- table_info: this.tableOrViewInfo,
857
- socket: undefined,
858
- table_rules,
859
- condition,
860
- func: localFunc,
861
- filter: { ...filter },
862
- params: { ...selectParams },
863
- socket_id: undefined,
864
- table_name: this.name,
865
- throttle,
866
- last_throttled: 0,
867
- }).then(channelName => ({ channelName }));
868
- const unsubscribe = async () => {
869
- const pubSubManager = await this.dboBuilder.getPubSubManager();
870
- pubSubManager.removeLocalSub(this.name, condition, localFunc)
871
- };
872
- let res: { unsubscribe: () => any } = Object.freeze({ unsubscribe })
873
- return res;
874
- }
875
- } catch (e) {
876
- if (localParams && localParams.testRule) throw e;
877
- throw parseError(e, `dbo.${this.name}.subscribe()`);
878
- }
721
+ async subscribe(filter: Filter, params: SubscribeParams, localFunc: LocalFunc): Promise<{ unsubscribe: () => any }>
722
+ async subscribe(filter: Filter, params: SubscribeParams, localFunc: undefined, table_rules: TableRule | undefined, localParams: LocalParams): Promise<string>
723
+ async subscribe(filter: Filter, params: SubscribeParams, localFunc?: LocalFunc, table_rules?: TableRule, localParams?: LocalParams):
724
+ Promise<{ unsubscribe: () => any } | string> {
725
+ //@ts-ignore
726
+ return subscribe.bind(this)(filter, params, localFunc, table_rules, localParams);
879
727
  }
880
728
 
881
729
  /* This should only be called from server */
882
730
  subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any): Promise<{ unsubscribe: () => any }>
883
- subscribeOne(filter: Filter, params: SubscribeParams, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams): Promise<string>
884
- subscribeOne(filter: Filter, params: SubscribeParams = {}, localFunc: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams):
731
+ subscribeOne(filter: Filter, params: SubscribeParams, localFunc: undefined, table_rules: TableRule, localParams: LocalParams): Promise<string>
732
+ subscribeOne(filter: Filter, params: SubscribeParams = {}, localFunc?: (item: AnyObject) => any, table_rules?: TableRule, localParams?: LocalParams):
885
733
  Promise<string | { unsubscribe: () => any }> {
886
- let func = localParams ? undefined : (rows: AnyObject[]) => localFunc(rows[0]);
887
- return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
734
+
735
+ //@ts-ignore
736
+ let func = localParams? undefined : (rows: AnyObject[]) => localFunc(rows[0]);
737
+ //@ts-ignore
738
+ return this.subscribe(filter, { ...params, limit: 2 }, func, table_rules, localParams);
888
739
  }
889
740
 
890
741
  async count(filter?: Filter, param2_unused?: undefined, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<number> {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports._delete = void 0;
4
4
  const prostgles_types_1 = require("prostgles-types");
5
5
  const DboBuilder_1 = require("../DboBuilder");
6
- const PubSubManager_1 = require("../PubSubManager");
6
+ const PubSubManager_1 = require("../PubSubManager/PubSubManager");
7
7
  async function _delete(filter, params, param3_unused, table_rules, localParams) {
8
8
  try {
9
9
  const { returning } = params || {};
@@ -2,7 +2,7 @@ import pgPromise from "pg-promise";
2
2
  import { AnyObject, asName, DeleteParams, FieldFilter } from "prostgles-types";
3
3
  import { Filter, LocalParams, makeErr, parseError } from "../DboBuilder";
4
4
  import { DeleteRule, TableRule } from "../PublishParser";
5
- import { pickKeys } from "../PubSubManager";
5
+ import { pickKeys } from "../PubSubManager/PubSubManager";
6
6
  import { TableHandler } from "./TableHandler";
7
7
 
8
8
  export async function _delete(this: TableHandler, filter?: Filter, params?: DeleteParams, param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<any> {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.insert = void 0;
4
4
  const prostgles_types_1 = require("prostgles-types");
5
5
  const DboBuilder_1 = require("../DboBuilder");
6
- const PubSubManager_1 = require("../PubSubManager");
6
+ const PubSubManager_1 = require("../PubSubManager/PubSubManager");
7
7
  async function insert(rowOrRows, param2, param3_unused, tableRules, localParams) {
8
8
  // const localParams = _localParams || {};
9
9
  const ACTION = "insert";
@@ -2,7 +2,7 @@ import pgPromise from "pg-promise";
2
2
  import { AnyObject, asName, FieldFilter, get, getKeys, InsertParams, isObject } from "prostgles-types";
3
3
  import { isPlainObject, LocalParams, makeErr, parseError, pgp } from "../DboBuilder";
4
4
  import { TableRule } from "../PublishParser";
5
- import { asValue, omitKeys, pickKeys } from "../PubSubManager";
5
+ import { asValue, omitKeys, pickKeys } from "../PubSubManager/PubSubManager";
6
6
  import { TableHandler } from "./TableHandler";
7
7
 
8
8
  export async function insert(this: TableHandler, rowOrRows: (AnyObject | AnyObject[]), param2?: InsertParams, param3_unused?: undefined, tableRules?: TableRule, localParams?: LocalParams): Promise<any | any[] | boolean> {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.insertDataParse = void 0;
4
4
  const prostgles_types_1 = require("prostgles-types");
5
- const PubSubManager_1 = require("../PubSubManager");
5
+ const PubSubManager_1 = require("../PubSubManager/PubSubManager");
6
6
  const uploadFile_1 = require("./uploadFile");
7
7
  /**
8
8
  * Used for doing referenced inserts within a single transaction
@@ -1,7 +1,7 @@
1
1
  import { AnyObject, getKeys, InsertParams, isDefined, isObject, PG_COLUMN_UDT_DATA_TYPE } from "prostgles-types";
2
2
  import { LocalParams, TableHandlers } from "../DboBuilder";
3
3
  import { TableRule } from "../PublishParser";
4
- import { omitKeys } from "../PubSubManager";
4
+ import { omitKeys } from "../PubSubManager/PubSubManager";
5
5
  import { TableHandler } from "./TableHandler";
6
6
  import { uploadFile } from "./uploadFile";
7
7
 
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.canCreateTables = exports.canRunSQL = exports.runSQL = void 0;
4
4
  const DboBuilder_1 = require("../DboBuilder");
5
- const PubSubManager_1 = require("../PubSubManager");
5
+ const PubSubManager_1 = require("../PubSubManager/PubSubManager");
6
6
  const { ParameterizedQuery: PQ } = require('pg-promise');
7
7
  async function runSQL(query, params, options, localParams) {
8
8
  if (query?.replace(/\s\s+/g, ' ').toLowerCase().includes("create extension pg_stat_statements")) {
@@ -1,7 +1,7 @@
1
1
  import { PG_COLUMN_UDT_DATA_TYPE, SQLHandler, SQLOptions, SQLResult } from "prostgles-types";
2
2
  import { DboBuilder, LocalParams, pgp, postgresToTsType } from "../DboBuilder";
3
3
  import { DB, Prostgles } from "../Prostgles";
4
- import { PubSubManager } from "../PubSubManager";
4
+ import { PubSubManager } from "../PubSubManager/PubSubManager";
5
5
  const { ParameterizedQuery: PQ } = require('pg-promise');
6
6
 
7
7
 
@@ -0,0 +1,11 @@
1
+ import { AnyObject, SubscribeParams } from "prostgles-types";
2
+ import { Filter, LocalParams } from "../DboBuilder";
3
+ import { TableRule } from "../PublishParser";
4
+ import { ViewHandler } from "./ViewHandler";
5
+ export declare type LocalFunc = (items: AnyObject[]) => any;
6
+ declare function subscribe(this: ViewHandler, filter: Filter, params: SubscribeParams, localFunc: LocalFunc): Promise<{
7
+ unsubscribe: () => any;
8
+ }>;
9
+ declare function subscribe(this: ViewHandler, filter: Filter, params: SubscribeParams, localFunc: undefined, table_rules: TableRule | undefined, localParams: LocalParams): Promise<string>;
10
+ export { subscribe };
11
+ //# sourceMappingURL=subscribe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.d.ts","sourceRoot":"","sources":["subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAU,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAuB,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,oBAAY,SAAS,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC;AAEpD,iBAAe,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,GAAG,CAAA;CAAE,CAAC,CAAA;AAC/I,iBAAe,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,GAAG,SAAS,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AA4NzL,OAAO,EAAE,SAAS,EAAE,CAAA"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.subscribe = void 0;
4
+ const prostgles_types_1 = require("prostgles-types");
5
+ const DboBuilder_1 = require("../DboBuilder");
6
+ const PubSubManager_1 = require("../PubSubManager/PubSubManager");
7
+ async function subscribe(filter, params, localFunc, table_rules, localParams) {
8
+ try {
9
+ // if (this.is_view) throw "Cannot subscribe to a view";
10
+ if (this.t) {
11
+ throw "subscribe not allowed within transactions";
12
+ }
13
+ if (!localParams && !localFunc) {
14
+ throw " missing data. provide -> localFunc | localParams { socket } ";
15
+ }
16
+ if (localParams?.socket && localFunc) {
17
+ console.error({ localParams, localFunc });
18
+ throw " Cannot have localFunc AND socket ";
19
+ }
20
+ 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"]);
21
+ /** app_triggers condition field has an index which limits it's value.
22
+ * TODO: use condition md5 hash
23
+ * */
24
+ const filterSize = JSON.stringify(filter || {}).length;
25
+ if (filterSize * 4 > 2704) {
26
+ throw "filter too big. Might exceed the btree version 4 maximum 2704. Use a primary key or a $rowhash filter instead";
27
+ }
28
+ if (!localFunc) {
29
+ if (!this.dboBuilder.prostgles.isSuperUser) {
30
+ throw "Subscribe not possible. Must be superuser to add triggers 1856";
31
+ }
32
+ return await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams)
33
+ .then(async (_isValid) => {
34
+ let viewOptions = undefined;
35
+ if (this.is_view) {
36
+ const viewName = this.name;
37
+ const viewNameEscaped = this.escapedName;
38
+ const { current_schema } = await this.db.oneOrNone("SELECT current_schema");
39
+ /** Get list of used columns and their parent tables */
40
+ let { def } = (await this.db.oneOrNone("SELECT pg_get_viewdef(${viewName}) as def", { viewName }));
41
+ def = def.trim();
42
+ if (def.endsWith(";")) {
43
+ def = def.slice(0, -1);
44
+ }
45
+ if (!def || typeof def !== "string") {
46
+ throw (0, DboBuilder_1.makeErr)("Could get view definition");
47
+ }
48
+ const { fields } = await this.dboBuilder.dbo.sql(`SELECT * FROM ( \n ${def} \n ) prostgles_subscribe_view_definition LIMIT 0`, {});
49
+ const tableColumns = fields.filter(f => f.tableName && f.columnName);
50
+ /** Create exists filters for each table */
51
+ const tableIds = Array.from(new Set(tableColumns.map(tc => tc.tableID.toString())));
52
+ viewOptions = {
53
+ viewName,
54
+ definition: def,
55
+ relatedTables: []
56
+ };
57
+ viewOptions.relatedTables = await Promise.all(tableIds.map(async (tableID) => {
58
+ const table = this.dboBuilder.USER_TABLES?.find(t => t.relid === +tableID);
59
+ let tableCols = tableColumns.filter(tc => tc.tableID.toString() === tableID);
60
+ /** If table has primary keys and they are all in this view then use only primary keys */
61
+ if (table?.pkey_columns?.every(pkey => tableCols.some(c => c.columnName === pkey))) {
62
+ tableCols = tableCols.filter(c => table?.pkey_columns?.includes(c.columnName));
63
+ }
64
+ else {
65
+ /** Exclude non comparable data types */
66
+ tableCols = tableCols.filter(c => !["json", "xml"].includes(c.udt_name));
67
+ }
68
+ const { relname: tableName, schemaname: tableSchema } = table;
69
+ if (tableCols.length) {
70
+ const tableNameEscaped = tableSchema === current_schema ? table.relname : [tableSchema, tableName].map(v => JSON.stringify(v)).join(".");
71
+ const fullCondition = `EXISTS (
72
+ SELECT 1
73
+ FROM ${viewNameEscaped}
74
+ WHERE ${tableCols.map(c => `${tableNameEscaped}.${JSON.stringify(c.columnName)} = ${viewNameEscaped}.${JSON.stringify(c.name)}`).join(" AND \n")}
75
+ AND ${condition || "TRUE"}
76
+ )`;
77
+ try {
78
+ const { count } = await this.db.oneOrNone(`
79
+ WITH ${(0, prostgles_types_1.asName)(tableName)} AS (
80
+ SELECT *
81
+ FROM ${(0, prostgles_types_1.asName)(tableName)}
82
+ LIMIT 0
83
+ )
84
+
85
+ SELECT *
86
+ FROM (
87
+ ${def}
88
+ ) prostgles_view_ref_table_test
89
+ `);
90
+ const relatedTableSubscription = {
91
+ tableName: tableName,
92
+ tableNameEscaped,
93
+ condition: fullCondition,
94
+ };
95
+ if (count.toString() === '0') {
96
+ return relatedTableSubscription;
97
+ }
98
+ }
99
+ catch (e) {
100
+ (0, PubSubManager_1.log)(`Could not not override subscribed view (${this.name}) table (${tableName}). Will not check condition`, e);
101
+ }
102
+ }
103
+ return {
104
+ tableName: tableName,
105
+ tableNameEscaped: JSON.stringify(tableName),
106
+ condition: "TRUE"
107
+ };
108
+ }));
109
+ /** Get list of remaining used inner tables */
110
+ const allUsedTables = await this.db.any("SELECT distinct table_name, table_schema FROM information_schema.view_column_usage WHERE view_name = ${viewName}", { viewName });
111
+ /** Remaining tables will have listeners on all records (condition = "TRUE") */
112
+ const remainingInnerTables = allUsedTables.filter(at => !tableColumns.some(dc => dc.tableName === at.table_name && dc.tableSchema === at.table_schema));
113
+ viewOptions.relatedTables = [
114
+ ...viewOptions.relatedTables,
115
+ ...remainingInnerTables.map(t => ({
116
+ tableName: t.table_name,
117
+ tableNameEscaped: [t.table_name, t.table_schema].map(v => JSON.stringify(v)).join("."),
118
+ condition: "TRUE"
119
+ }))
120
+ ];
121
+ if (!viewOptions.relatedTables.length) {
122
+ throw "Could not subscribe to this view: no related tables found";
123
+ }
124
+ }
125
+ const { socket } = localParams ?? {};
126
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
127
+ return pubSubManager.addSub({
128
+ table_info: this.tableOrViewInfo,
129
+ socket,
130
+ table_rules,
131
+ table_name: this.name,
132
+ condition: condition,
133
+ viewOptions,
134
+ func: undefined,
135
+ filter: { ...filter },
136
+ params: { ...selectParams },
137
+ socket_id: socket?.id,
138
+ throttle,
139
+ last_throttled: 0,
140
+ }).then(channelName => ({ channelName }));
141
+ });
142
+ }
143
+ else {
144
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
145
+ pubSubManager.addSub({
146
+ table_info: this.tableOrViewInfo,
147
+ socket: undefined,
148
+ table_rules,
149
+ condition,
150
+ func: localFunc,
151
+ filter: { ...filter },
152
+ params: { ...selectParams },
153
+ socket_id: undefined,
154
+ table_name: this.name,
155
+ throttle,
156
+ last_throttled: 0,
157
+ }).then(channelName => ({ channelName }));
158
+ const unsubscribe = async () => {
159
+ const pubSubManager = await this.dboBuilder.getPubSubManager();
160
+ pubSubManager.removeLocalSub(this.name, condition, localFunc);
161
+ };
162
+ let res = Object.freeze({ unsubscribe });
163
+ return res;
164
+ }
165
+ }
166
+ catch (e) {
167
+ if (localParams && localParams.testRule)
168
+ throw e;
169
+ throw (0, DboBuilder_1.parseError)(e, `dbo.${this.name}.subscribe()`);
170
+ }
171
+ }
172
+ exports.subscribe = subscribe;
173
+ async function _subscribe(localFunc, table_rules, localParams) {
174
+ if (localFunc && !localParams) {
175
+ return {
176
+ unsubscribe: () => { }
177
+ };
178
+ }
179
+ if (localParams) {
180
+ return "";
181
+ }
182
+ return {
183
+ unsubscribe: () => { }
184
+ };
185
+ }
186
+ const d = async () => {
187
+ const res = await _subscribe(() => { });
188
+ const res2 = await _subscribe(undefined, {}, {});
189
+ };