prostgles-server 2.0.249 → 2.0.252

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 (44) hide show
  1. package/dist/DboBuilder/delete.js +2 -2
  2. package/dist/DboBuilder/delete.js.map +1 -1
  3. package/dist/DboBuilder/insert.d.ts +1 -1
  4. package/dist/DboBuilder/insert.d.ts.map +1 -1
  5. package/dist/DboBuilder/insert.js +25 -16
  6. package/dist/DboBuilder/insert.js.map +1 -1
  7. package/dist/DboBuilder/insertDataParse.d.ts.map +1 -1
  8. package/dist/DboBuilder/insertDataParse.js +4 -3
  9. package/dist/DboBuilder/insertDataParse.js.map +1 -1
  10. package/dist/DboBuilder/update.d.ts.map +1 -1
  11. package/dist/DboBuilder/update.js +39 -7
  12. package/dist/DboBuilder/update.js.map +1 -1
  13. package/dist/DboBuilder.d.ts +6 -3
  14. package/dist/DboBuilder.d.ts.map +1 -1
  15. package/dist/DboBuilder.js +178 -93
  16. package/dist/DboBuilder.js.map +1 -1
  17. package/dist/PublishParser.d.ts +7 -1
  18. package/dist/PublishParser.d.ts.map +1 -1
  19. package/dist/PublishParser.js.map +1 -1
  20. package/lib/DboBuilder/delete.js +2 -2
  21. package/lib/DboBuilder/delete.ts +2 -2
  22. package/lib/DboBuilder/insert.d.ts +1 -1
  23. package/lib/DboBuilder/insert.d.ts.map +1 -1
  24. package/lib/DboBuilder/insert.js +25 -16
  25. package/lib/DboBuilder/insert.ts +33 -17
  26. package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
  27. package/lib/DboBuilder/insertDataParse.js +4 -3
  28. package/lib/DboBuilder/insertDataParse.ts +5 -4
  29. package/lib/DboBuilder/update.d.ts.map +1 -1
  30. package/lib/DboBuilder/update.js +39 -7
  31. package/lib/DboBuilder/update.ts +44 -8
  32. package/lib/DboBuilder.d.ts +6 -3
  33. package/lib/DboBuilder.d.ts.map +1 -1
  34. package/lib/DboBuilder.js +178 -93
  35. package/lib/DboBuilder.ts +207 -98
  36. package/lib/PublishParser.d.ts +7 -1
  37. package/lib/PublishParser.d.ts.map +1 -1
  38. package/lib/PublishParser.ts +7 -1
  39. package/package.json +1 -1
  40. package/tests/client/PID.txt +1 -1
  41. package/tests/isomorphic_queries.ts +1 -1
  42. package/tests/server/index.js +9 -1
  43. package/tests/server/index.ts +9 -1
  44. package/tests/server/package-lock.json +1 -1
@@ -1816,6 +1816,8 @@ class TableHandler extends ViewHandler {
1816
1816
  }
1817
1817
  }
1818
1818
  exports.TableHandler = TableHandler;
1819
+ let DATA_TYPES;
1820
+ let USER_TABLES;
1819
1821
  const Prostgles_1 = require("./Prostgles");
1820
1822
  const DBSchemaBuilder_1 = require("./DBSchemaBuilder");
1821
1823
  class DboBuilder {
@@ -1859,15 +1861,112 @@ class DboBuilder {
1859
1861
  }
1860
1862
  return this;
1861
1863
  };
1864
+ this.runSQL = async (query, params, options, localParams) => {
1865
+ /** Cache types */
1866
+ DATA_TYPES ?? (DATA_TYPES = await this.db.any("SELECT oid, typname FROM pg_type") ?? []);
1867
+ USER_TABLES ?? (USER_TABLES = await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables") ?? []);
1868
+ const canRunSQL = async (localParams) => {
1869
+ if (!localParams?.socket || !localParams?.httpReq)
1870
+ return true;
1871
+ const { socket } = localParams;
1872
+ const publishParams = await this.prostgles.publishParser.getPublishParams({ socket });
1873
+ let res = await this.prostgles.opts.publishRawSQL?.(publishParams);
1874
+ return Boolean(res && typeof res === "boolean" || res === "*");
1875
+ };
1876
+ if (!(await canRunSQL(localParams)))
1877
+ throw "Not allowed to run SQL";
1878
+ const { returnType, allowListen } = options || {};
1879
+ const { socket } = localParams || {};
1880
+ const db = localParams?.tx?.t || this.db;
1881
+ if (returnType === "noticeSubscription") {
1882
+ if (!socket)
1883
+ throw "Only allowed with client socket";
1884
+ return await this.prostgles.dbEventsManager?.addNotice(socket);
1885
+ }
1886
+ else if (returnType === "statement") {
1887
+ try {
1888
+ return exports.pgp.as.format(query, params);
1889
+ }
1890
+ catch (err) {
1891
+ throw err.toString();
1892
+ }
1893
+ }
1894
+ else if (db) {
1895
+ let finalQuery = query + "";
1896
+ if (returnType === "arrayMode" && !["listen ", "notify "].find(c => query.toLowerCase().trim().startsWith(c))) {
1897
+ finalQuery = new PQ({ text: exports.pgp.as.format(query, params), rowMode: "array" });
1898
+ }
1899
+ let _qres = await db.result(finalQuery, params);
1900
+ const { fields, rows, command } = _qres;
1901
+ /**
1902
+ * Fallback for watchSchema in case not superuser and cannot add db event listener
1903
+ */
1904
+ const { watchSchema, watchSchemaType } = this.prostgles?.opts || {};
1905
+ if (watchSchema &&
1906
+ (!this.prostgles.isSuperUser || watchSchemaType === "prostgles_queries")) {
1907
+ if (["CREATE", "ALTER", "DROP"].includes(command)) {
1908
+ this.prostgles.onSchemaChange({ command, query });
1909
+ }
1910
+ else if (query) {
1911
+ const cleanedQuery = query.toLowerCase().replace(/\s\s+/g, ' ');
1912
+ if (PubSubManager_1.PubSubManager.SCHEMA_ALTERING_QUERIES.some(q => cleanedQuery.includes(q.toLowerCase()))) {
1913
+ this.prostgles.onSchemaChange({ command, query });
1914
+ }
1915
+ }
1916
+ }
1917
+ if (command === "LISTEN") {
1918
+ if (!allowListen)
1919
+ throw new Error(`Your query contains a LISTEN command. Set { allowListen: true } to get subscription hooks. Or ignore this message`);
1920
+ if (!socket)
1921
+ throw "Only allowed with client socket";
1922
+ return await this.prostgles.dbEventsManager?.addNotify(query, socket);
1923
+ }
1924
+ else if (returnType === "rows") {
1925
+ return rows;
1926
+ }
1927
+ else if (returnType === "row") {
1928
+ return rows[0];
1929
+ }
1930
+ else if (returnType === "value") {
1931
+ return Object.values(rows?.[0] || {})?.[0];
1932
+ }
1933
+ else if (returnType === "values") {
1934
+ return rows.map(r => Object.values(r[0]));
1935
+ }
1936
+ else {
1937
+ let qres = {
1938
+ duration: 0,
1939
+ ..._qres,
1940
+ fields: fields?.map(f => {
1941
+ const dataType = DATA_TYPES.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text", tableName = USER_TABLES.find(t => +t.relid === +f.tableID), tsDataType = postgresToTsType(dataType);
1942
+ return {
1943
+ ...f,
1944
+ tsDataType,
1945
+ dataType,
1946
+ udt_name: dataType,
1947
+ tableName: tableName?.relname
1948
+ };
1949
+ }) ?? []
1950
+ };
1951
+ return qres;
1952
+ }
1953
+ }
1954
+ else
1955
+ console.error("db missing");
1956
+ };
1862
1957
  this.getTX = (cb) => {
1863
1958
  return this.db.tx((t) => {
1864
1959
  let dbTX = {};
1865
1960
  this.tablesOrViews?.map(tov => {
1866
1961
  dbTX[tov.name] = new (tov.is_view ? ViewHandler : TableHandler)(this.db, tov, this, t, dbTX, this.joinPaths);
1867
1962
  });
1963
+ if (!dbTX.sql) {
1964
+ dbTX.sql = this.runSQL;
1965
+ }
1868
1966
  (0, prostgles_types_1.getKeys)(dbTX).map(k => {
1869
1967
  dbTX[k].dbTX = dbTX;
1870
1968
  });
1969
+ dbTX.sql = (q, args, opts, localP) => this.runSQL(q, args, opts, { tx: { dbTX, t }, ...(localP ?? {}) });
1871
1970
  return cb(dbTX, t);
1872
1971
  });
1873
1972
  };
@@ -2030,98 +2129,84 @@ class DboBuilder {
2030
2129
  this.dbo[txKey] = (cb) => this.getTX(cb);
2031
2130
  }
2032
2131
  if (!this.dbo.sql) {
2033
- let needType = true;
2034
- let DATA_TYPES = !needType ? [] : await this.db.any("SELECT oid, typname FROM pg_type");
2035
- let USER_TABLES = !needType ? [] : await this.db.any("SELECT relid, relname FROM pg_catalog.pg_statio_user_tables");
2036
- this.dbo.sql = async (query, params, options, localParams) => {
2037
- const canRunSQL = async (localParams) => {
2038
- if (!localParams)
2039
- return true;
2040
- const { socket } = localParams;
2041
- const publishParams = await this.prostgles.publishParser.getPublishParams({ socket });
2042
- let res = await this.prostgles.opts.publishRawSQL?.(publishParams);
2043
- return Boolean(res && typeof res === "boolean" || res === "*");
2044
- };
2045
- if (!(await canRunSQL(localParams)))
2046
- throw "Not allowed to run SQL";
2047
- const { returnType, allowListen } = options || {};
2048
- const { socket } = localParams || {};
2049
- if (returnType === "noticeSubscription") {
2050
- if (!socket)
2051
- throw "Only allowed with client socket";
2052
- return await this.prostgles.dbEventsManager?.addNotice(socket);
2053
- }
2054
- else if (returnType === "statement") {
2055
- try {
2056
- return exports.pgp.as.format(query, params);
2057
- }
2058
- catch (err) {
2059
- throw err.toString();
2060
- }
2061
- }
2062
- else if (this.db) {
2063
- let finalQuery = query + "";
2064
- if (returnType === "arrayMode" && !["listen ", "notify "].find(c => query.toLowerCase().trim().startsWith(c))) {
2065
- finalQuery = new PQ({ text: exports.pgp.as.format(query, params), rowMode: "array" });
2066
- }
2067
- let _qres = await this.db.result(finalQuery, params);
2068
- const { fields, rows, command } = _qres;
2069
- /**
2070
- * Fallback for watchSchema in case not superuser and cannot add db event listener
2071
- */
2072
- const { watchSchema, watchSchemaType } = this.prostgles?.opts || {};
2073
- if (watchSchema &&
2074
- (!this.prostgles.isSuperUser || watchSchemaType === "prostgles_queries")) {
2075
- if (["CREATE", "ALTER", "DROP"].includes(command)) {
2076
- this.prostgles.onSchemaChange({ command, query });
2077
- }
2078
- else if (query) {
2079
- const cleanedQuery = query.toLowerCase().replace(/\s\s+/g, ' ');
2080
- if (PubSubManager_1.PubSubManager.SCHEMA_ALTERING_QUERIES.some(q => cleanedQuery.includes(q.toLowerCase()))) {
2081
- this.prostgles.onSchemaChange({ command, query });
2082
- }
2083
- }
2084
- }
2085
- if (command === "LISTEN") {
2086
- if (!allowListen)
2087
- throw new Error(`Your query contains a LISTEN command. Set { allowListen: true } to get subscription hooks. Or ignore this message`);
2088
- if (!socket)
2089
- throw "Only allowed with client socket";
2090
- return await this.prostgles.dbEventsManager?.addNotify(query, socket);
2091
- }
2092
- else if (returnType === "rows") {
2093
- return rows;
2094
- }
2095
- else if (returnType === "row") {
2096
- return rows[0];
2097
- }
2098
- else if (returnType === "value") {
2099
- return Object.values(rows?.[0] || {})?.[0];
2100
- }
2101
- else if (returnType === "values") {
2102
- return rows.map(r => Object.values(r[0]));
2103
- }
2104
- else {
2105
- let qres = {
2106
- duration: 0,
2107
- ..._qres,
2108
- fields: fields?.map(f => {
2109
- const dataType = DATA_TYPES.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text", tableName = USER_TABLES.find(t => +t.relid === +f.tableID), tsDataType = postgresToTsType(dataType);
2110
- return {
2111
- ...f,
2112
- tsDataType,
2113
- dataType,
2114
- udt_name: dataType,
2115
- tableName: tableName?.relname
2116
- };
2117
- }) ?? []
2118
- };
2119
- return qres;
2120
- }
2121
- }
2122
- else
2123
- console.error("db missing");
2124
- };
2132
+ this.dbo.sql = this.runSQL;
2133
+ // this.dbo.sql = async (query: string, params: any, options: SQLOptions | undefined, localParams?: LocalParams) => {
2134
+ // const canRunSQL = async (localParams?: LocalParams) => {
2135
+ // if(!localParams?.socket || !localParams?.httpReq) return true;
2136
+ // const { socket } = localParams;
2137
+ // const publishParams = await this.prostgles.publishParser!.getPublishParams({ socket });
2138
+ // let res = await this.prostgles.opts.publishRawSQL?.(publishParams);
2139
+ // return Boolean(res && typeof res === "boolean" || res === "*");
2140
+ // }
2141
+ // if(!(await canRunSQL(localParams))) throw "Not allowed to run SQL";
2142
+ // const { returnType, allowListen }: SQLOptions = options || ({} as any);
2143
+ // const { socket } = localParams || {};
2144
+ // if(returnType === "noticeSubscription"){
2145
+ // if(!socket) throw "Only allowed with client socket"
2146
+ // return await this.prostgles.dbEventsManager?.addNotice(socket);
2147
+ // } else if(returnType === "statement"){
2148
+ // try {
2149
+ // return pgp.as.format(query, params);
2150
+ // } catch (err){
2151
+ // throw (err as any).toString();
2152
+ // }
2153
+ // } else if(this.db) {
2154
+ // let finalQuery = query + "";
2155
+ // if(returnType === "arrayMode" && !["listen ", "notify "].find(c => query.toLowerCase().trim().startsWith(c))){
2156
+ // finalQuery = new PQ({ text: pgp.as.format(query, params), rowMode: "array" });
2157
+ // }
2158
+ // let _qres = await this.db.result(finalQuery, params)
2159
+ // const { fields, rows, command } = _qres;
2160
+ // /**
2161
+ // * Fallback for watchSchema in case not superuser and cannot add db event listener
2162
+ // */
2163
+ // const { watchSchema, watchSchemaType } = this.prostgles?.opts || {};
2164
+ // if(
2165
+ // watchSchema &&
2166
+ // (!this.prostgles.isSuperUser || watchSchemaType === "prostgles_queries")
2167
+ // ){
2168
+ // if(["CREATE", "ALTER", "DROP"].includes(command)){
2169
+ // this.prostgles.onSchemaChange({ command, query })
2170
+ // } else if(query) {
2171
+ // const cleanedQuery = query.toLowerCase().replace(/\s\s+/g, ' ');
2172
+ // if(PubSubManager.SCHEMA_ALTERING_QUERIES.some(q => cleanedQuery.includes(q.toLowerCase()))){
2173
+ // this.prostgles.onSchemaChange({ command, query })
2174
+ // }
2175
+ // }
2176
+ // }
2177
+ // if(command === "LISTEN"){
2178
+ // if(!allowListen) throw new Error(`Your query contains a LISTEN command. Set { allowListen: true } to get subscription hooks. Or ignore this message`)
2179
+ // if(!socket) throw "Only allowed with client socket"
2180
+ // return await this.prostgles.dbEventsManager?.addNotify(query, socket);
2181
+ // } else if(returnType === "rows") {
2182
+ // return rows;
2183
+ // } else if(returnType === "row") {
2184
+ // return rows[0];
2185
+ // } else if(returnType === "value") {
2186
+ // return Object.values(rows?.[0] || {})?.[0];
2187
+ // } else if(returnType === "values") {
2188
+ // return rows.map(r => Object.values(r[0]));
2189
+ // } else {
2190
+ // let qres: SQLResult<typeof returnType> = {
2191
+ // duration: 0,
2192
+ // ..._qres,
2193
+ // fields: fields?.map(f => {
2194
+ // const dataType = DATA_TYPES.find(dt => +dt.oid === +f.dataTypeID)?.typname ?? "text",
2195
+ // tableName = USER_TABLES.find(t => +t.relid === +f.tableID),
2196
+ // tsDataType = postgresToTsType(dataType);
2197
+ // return {
2198
+ // ...f,
2199
+ // tsDataType,
2200
+ // dataType,
2201
+ // udt_name: dataType,
2202
+ // tableName: tableName?.relname
2203
+ // }
2204
+ // }) ?? []
2205
+ // };
2206
+ // return qres;
2207
+ // }
2208
+ // } else console.error("db missing");
2209
+ // }
2125
2210
  }
2126
2211
  else {
2127
2212
  console.warn(`Could not create dbo.sql handler because there is already a table named "sql"`);
@@ -2201,7 +2286,7 @@ async function getTablesForSchemaPostgresSQL(db, schema = "public") {
2201
2286
  , array_to_json(vr.table_names) as parent_tables
2202
2287
  , obj_description(cc.table_oid::regclass) as comment
2203
2288
  FROM information_schema.tables t
2204
- INNER join (
2289
+ LEFT JOIN ( -- INNER join slows things down
2205
2290
  SELECT c.table_schema, c.table_name, c.column_name, c.data_type, c.udt_name
2206
2291
  , e.data_type as element_type
2207
2292
  , e.udt_name as element_udt_name