@powersync/service-module-postgres 0.16.2 → 0.16.3
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/CHANGELOG.md +14 -0
- package/dist/api/PostgresRouteAPIAdapter.d.ts +1 -0
- package/dist/api/PostgresRouteAPIAdapter.js +8 -1
- package/dist/api/PostgresRouteAPIAdapter.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/module/PostgresModule.d.ts +1 -0
- package/dist/module/PostgresModule.js +9 -4
- package/dist/module/PostgresModule.js.map +1 -1
- package/dist/replication/ConnectionManagerFactory.d.ts +3 -1
- package/dist/replication/ConnectionManagerFactory.js +4 -2
- package/dist/replication/ConnectionManagerFactory.js.map +1 -1
- package/dist/replication/PgManager.d.ts +8 -2
- package/dist/replication/PgManager.js +5 -4
- package/dist/replication/PgManager.js.map +1 -1
- package/dist/replication/PgRelation.d.ts +1 -0
- package/dist/replication/PgRelation.js +7 -0
- package/dist/replication/PgRelation.js.map +1 -1
- package/dist/replication/WalStream.d.ts +6 -1
- package/dist/replication/WalStream.js +45 -33
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/types/registry.d.ts +69 -0
- package/dist/types/registry.js +196 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/resolver.d.ts +47 -0
- package/dist/types/resolver.js +191 -0
- package/dist/types/resolver.js.map +1 -0
- package/dist/types/types.d.ts +4 -1
- package/dist/types/types.js.map +1 -1
- package/dist/utils/postgres_version.d.ts +3 -0
- package/dist/utils/postgres_version.js +7 -0
- package/dist/utils/postgres_version.js.map +1 -0
- package/package.json +10 -10
- package/src/api/PostgresRouteAPIAdapter.ts +9 -1
- package/src/index.ts +0 -2
- package/src/module/PostgresModule.ts +10 -4
- package/src/replication/ConnectionManagerFactory.ts +6 -2
- package/src/replication/PgManager.ts +12 -4
- package/src/replication/PgRelation.ts +9 -0
- package/src/replication/WalStream.ts +49 -30
- package/src/types/registry.ts +278 -0
- package/src/types/resolver.ts +210 -0
- package/src/types/types.ts +5 -1
- package/src/utils/postgres_version.ts +8 -0
- package/test/src/pg_test.test.ts +152 -5
- package/test/src/route_api_adapter.test.ts +60 -0
- package/test/src/schema_changes.test.ts +32 -0
- package/test/src/slow_tests.test.ts +3 -2
- package/test/src/types/registry.test.ts +149 -0
- package/test/src/util.ts +16 -0
- package/test/src/wal_stream.test.ts +24 -0
- package/test/src/wal_stream_utils.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/pgwire_utils.d.ts +0 -17
- package/dist/utils/pgwire_utils.js +0 -43
- package/dist/utils/pgwire_utils.js.map +0 -1
- package/src/utils/pgwire_utils.ts +0 -48
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @powersync/service-module-postgres
|
|
2
2
|
|
|
3
|
+
## 0.16.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9681b4c: Add the `custom_postgres_types` compatibility option. When enabled, domain, composite, enum, range, multirange and custom array types will get synced in a JSON representation instead of the raw postgres wire format.
|
|
8
|
+
- Updated dependencies [9681b4c]
|
|
9
|
+
- Updated dependencies [9681b4c]
|
|
10
|
+
- Updated dependencies [f1b4cef]
|
|
11
|
+
- @powersync/service-sync-rules@0.29.1
|
|
12
|
+
- @powersync/service-jpgwire@0.21.0
|
|
13
|
+
- @powersync/service-core@1.15.3
|
|
14
|
+
- @powersync/lib-services-framework@0.7.4
|
|
15
|
+
- @powersync/lib-service-postgres@0.4.8
|
|
16
|
+
|
|
3
17
|
## 0.16.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -6,6 +6,7 @@ import * as types from '../types/types.js';
|
|
|
6
6
|
export declare class PostgresRouteAPIAdapter implements api.RouteAPI {
|
|
7
7
|
protected pool: pgwire.PgClient;
|
|
8
8
|
private config?;
|
|
9
|
+
private typeCache;
|
|
9
10
|
connectionTag: string;
|
|
10
11
|
publicationName: string;
|
|
11
12
|
static withConfig(config: types.ResolvedConnectionConfig): PostgresRouteAPIAdapter;
|
|
@@ -8,9 +8,12 @@ import { getDebugTableInfo } from '../replication/replication-utils.js';
|
|
|
8
8
|
import { KEEPALIVE_STATEMENT, PUBLICATION_NAME } from '../replication/WalStream.js';
|
|
9
9
|
import * as types from '../types/types.js';
|
|
10
10
|
import { getApplicationName } from '../utils/application-name.js';
|
|
11
|
+
import { CustomTypeRegistry } from '../types/registry.js';
|
|
12
|
+
import { PostgresTypeResolver } from '../types/resolver.js';
|
|
11
13
|
export class PostgresRouteAPIAdapter {
|
|
12
14
|
pool;
|
|
13
15
|
config;
|
|
16
|
+
typeCache;
|
|
14
17
|
connectionTag;
|
|
15
18
|
// TODO this should probably be configurable one day
|
|
16
19
|
publicationName = PUBLICATION_NAME;
|
|
@@ -27,6 +30,7 @@ export class PostgresRouteAPIAdapter {
|
|
|
27
30
|
constructor(pool, connectionTag, config) {
|
|
28
31
|
this.pool = pool;
|
|
29
32
|
this.config = config;
|
|
33
|
+
this.typeCache = new PostgresTypeResolver(config?.typeRegistry ?? new CustomTypeRegistry(), pool);
|
|
30
34
|
this.connectionTag = connectionTag ?? sync_rules.DEFAULT_TAG;
|
|
31
35
|
}
|
|
32
36
|
getParseSyncRulesOptions() {
|
|
@@ -262,6 +266,7 @@ LEFT JOIN (
|
|
|
262
266
|
SELECT
|
|
263
267
|
attrelid,
|
|
264
268
|
attname,
|
|
269
|
+
atttypid,
|
|
265
270
|
format_type(atttypid, atttypmod) as data_type,
|
|
266
271
|
(SELECT typname FROM pg_catalog.pg_type WHERE oid = atttypid) as pg_type,
|
|
267
272
|
attnum,
|
|
@@ -275,6 +280,7 @@ LEFT JOIN (
|
|
|
275
280
|
AND has_column_privilege(tbl.quoted_name, a.attname, 'SELECT, INSERT, UPDATE, REFERENCES')
|
|
276
281
|
)
|
|
277
282
|
GROUP BY schemaname, tablename, quoted_name`);
|
|
283
|
+
await this.typeCache.fetchTypesForSchema();
|
|
278
284
|
const rows = pgwire.pgwireRows(results);
|
|
279
285
|
let schemas = {};
|
|
280
286
|
for (let row of rows) {
|
|
@@ -293,9 +299,10 @@ GROUP BY schemaname, tablename, quoted_name`);
|
|
|
293
299
|
if (pg_type.startsWith('_')) {
|
|
294
300
|
pg_type = `${pg_type.substring(1)}[]`;
|
|
295
301
|
}
|
|
302
|
+
const knownType = this.typeCache.registry.lookupType(Number(column.atttypid));
|
|
296
303
|
table.columns.push({
|
|
297
304
|
name: column.attname,
|
|
298
|
-
sqlite_type: sync_rules.
|
|
305
|
+
sqlite_type: sync_rules.ExpressionType.fromTypeText(knownType.sqliteType()).typeFlags,
|
|
299
306
|
type: column.data_type,
|
|
300
307
|
internal_type: column.data_type,
|
|
301
308
|
pg_type: pg_type
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/PostgresRouteAPIAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAE5E,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,iBAAiB,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"PostgresRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/PostgresRouteAPIAdapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { api, ConnectionTestResult, modules, replication, system } from '@powers
|
|
|
3
3
|
import * as types from '../types/types.js';
|
|
4
4
|
import { PostgresConnectionConfig } from '../types/types.js';
|
|
5
5
|
export declare class PostgresModule extends replication.ReplicationModule<types.PostgresConnectionConfig> {
|
|
6
|
+
private customTypes;
|
|
6
7
|
constructor();
|
|
7
8
|
onInitialized(context: system.ServiceContextContainer): Promise<void>;
|
|
8
9
|
protected createRouteAPIAdapter(): api.RouteAPI;
|
|
@@ -11,7 +11,9 @@ import { PUBLICATION_NAME } from '../replication/WalStream.js';
|
|
|
11
11
|
import { WalStreamReplicator } from '../replication/WalStreamReplicator.js';
|
|
12
12
|
import * as types from '../types/types.js';
|
|
13
13
|
import { getApplicationName } from '../utils/application-name.js';
|
|
14
|
+
import { CustomTypeRegistry } from '../types/registry.js';
|
|
14
15
|
export class PostgresModule extends replication.ReplicationModule {
|
|
16
|
+
customTypes = new CustomTypeRegistry();
|
|
15
17
|
constructor() {
|
|
16
18
|
super({
|
|
17
19
|
name: 'Postgres',
|
|
@@ -36,7 +38,7 @@ export class PostgresModule extends replication.ReplicationModule {
|
|
|
36
38
|
createReplicator(context) {
|
|
37
39
|
const normalisedConfig = this.resolveConfig(this.decodedConfig);
|
|
38
40
|
const syncRuleProvider = new ConfigurationFileSyncRulesProvider(context.configuration.sync_rules);
|
|
39
|
-
const connectionFactory = new ConnectionManagerFactory(normalisedConfig);
|
|
41
|
+
const connectionFactory = new ConnectionManagerFactory(normalisedConfig, this.customTypes);
|
|
40
42
|
return new WalStreamReplicator({
|
|
41
43
|
id: this.getDefaultId(normalisedConfig.database),
|
|
42
44
|
syncRuleProvider: syncRuleProvider,
|
|
@@ -52,7 +54,8 @@ export class PostgresModule extends replication.ReplicationModule {
|
|
|
52
54
|
resolveConfig(config) {
|
|
53
55
|
return {
|
|
54
56
|
...config,
|
|
55
|
-
...types.normalizeConnectionConfig(config)
|
|
57
|
+
...types.normalizeConnectionConfig(config),
|
|
58
|
+
typeRegistry: this.customTypes
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
async teardown(options) {
|
|
@@ -60,7 +63,8 @@ export class PostgresModule extends replication.ReplicationModule {
|
|
|
60
63
|
const connectionManager = new PgManager(normalisedConfig, {
|
|
61
64
|
idleTimeout: 30_000,
|
|
62
65
|
maxSize: 1,
|
|
63
|
-
applicationName: getApplicationName()
|
|
66
|
+
applicationName: getApplicationName(),
|
|
67
|
+
registry: this.customTypes
|
|
64
68
|
});
|
|
65
69
|
try {
|
|
66
70
|
if (options.syncRules) {
|
|
@@ -90,7 +94,8 @@ export class PostgresModule extends replication.ReplicationModule {
|
|
|
90
94
|
const connectionManager = new PgManager(normalizedConfig, {
|
|
91
95
|
idleTimeout: 30_000,
|
|
92
96
|
maxSize: 1,
|
|
93
|
-
applicationName: getApplicationName()
|
|
97
|
+
applicationName: getApplicationName(),
|
|
98
|
+
registry: new CustomTypeRegistry()
|
|
94
99
|
});
|
|
95
100
|
const connection = await connectionManager.snapshotConnection();
|
|
96
101
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresModule.js","sourceRoot":"","sources":["../../src/module/PostgresModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA0C,MAAM,iCAAiC,CAAC;AAClG,OAAO,EAEL,kCAAkC,EAGlC,WAAW,EAEZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AACvG,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"PostgresModule.js","sourceRoot":"","sources":["../../src/module/PostgresModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { PgManager } from './PgManager.js';
|
|
2
2
|
import { NormalizedPostgresConnectionConfig } from '../types/types.js';
|
|
3
3
|
import { PgPoolOptions } from '@powersync/service-jpgwire';
|
|
4
|
+
import { CustomTypeRegistry } from '../types/registry.js';
|
|
4
5
|
export declare class ConnectionManagerFactory {
|
|
6
|
+
private readonly registry;
|
|
5
7
|
private readonly connectionManagers;
|
|
6
8
|
readonly dbConnectionConfig: NormalizedPostgresConnectionConfig;
|
|
7
|
-
constructor(dbConnectionConfig: NormalizedPostgresConnectionConfig);
|
|
9
|
+
constructor(dbConnectionConfig: NormalizedPostgresConnectionConfig, registry: CustomTypeRegistry);
|
|
8
10
|
create(poolOptions: PgPoolOptions): PgManager;
|
|
9
11
|
shutdown(): Promise<void>;
|
|
10
12
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { PgManager } from './PgManager.js';
|
|
2
2
|
import { logger } from '@powersync/lib-services-framework';
|
|
3
3
|
export class ConnectionManagerFactory {
|
|
4
|
+
registry;
|
|
4
5
|
connectionManagers;
|
|
5
6
|
dbConnectionConfig;
|
|
6
|
-
constructor(dbConnectionConfig) {
|
|
7
|
+
constructor(dbConnectionConfig, registry) {
|
|
8
|
+
this.registry = registry;
|
|
7
9
|
this.dbConnectionConfig = dbConnectionConfig;
|
|
8
10
|
this.connectionManagers = [];
|
|
9
11
|
}
|
|
10
12
|
create(poolOptions) {
|
|
11
|
-
const manager = new PgManager(this.dbConnectionConfig, poolOptions);
|
|
13
|
+
const manager = new PgManager(this.dbConnectionConfig, { ...poolOptions, registry: this.registry });
|
|
12
14
|
this.connectionManagers.push(manager);
|
|
13
15
|
return manager;
|
|
14
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionManagerFactory.js","sourceRoot":"","sources":["../../src/replication/ConnectionManagerFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectionManagerFactory.js","sourceRoot":"","sources":["../../src/replication/ConnectionManagerFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAG3D,MAAM,OAAO,wBAAwB;IAMhB;IALF,kBAAkB,CAAc;IACjC,kBAAkB,CAAqC;IAEvE,YACE,kBAAsD,EACrC,QAA4B;QAA5B,aAAQ,GAAR,QAAQ,CAAoB;QAE7C,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;QAC7C,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,WAA0B;QAC/B,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC7D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC9C,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC;CACF"}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
2
2
|
import semver from 'semver';
|
|
3
3
|
import { NormalizedPostgresConnectionConfig } from '../types/types.js';
|
|
4
|
+
import { PostgresTypeResolver } from '../types/resolver.js';
|
|
5
|
+
import { CustomTypeRegistry } from '../types/registry.js';
|
|
6
|
+
export interface PgManagerOptions extends pgwire.PgPoolOptions {
|
|
7
|
+
registry: CustomTypeRegistry;
|
|
8
|
+
}
|
|
4
9
|
export declare class PgManager {
|
|
5
10
|
options: NormalizedPostgresConnectionConfig;
|
|
6
|
-
poolOptions:
|
|
11
|
+
poolOptions: PgManagerOptions;
|
|
7
12
|
/**
|
|
8
13
|
* Do not use this for any transactions.
|
|
9
14
|
*/
|
|
10
15
|
readonly pool: pgwire.PgClient;
|
|
16
|
+
readonly types: PostgresTypeResolver;
|
|
11
17
|
private connectionPromises;
|
|
12
|
-
constructor(options: NormalizedPostgresConnectionConfig, poolOptions:
|
|
18
|
+
constructor(options: NormalizedPostgresConnectionConfig, poolOptions: PgManagerOptions);
|
|
13
19
|
get connectionTag(): string;
|
|
14
20
|
/**
|
|
15
21
|
* Create a new replication connection.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
2
|
-
import semver from 'semver';
|
|
3
2
|
import { getApplicationName } from '../utils/application-name.js';
|
|
3
|
+
import { PostgresTypeResolver } from '../types/resolver.js';
|
|
4
|
+
import { getServerVersion } from '../utils/postgres_version.js';
|
|
4
5
|
/**
|
|
5
6
|
* Shorter timeout for snapshot connections than for replication connections.
|
|
6
7
|
*/
|
|
@@ -12,12 +13,14 @@ export class PgManager {
|
|
|
12
13
|
* Do not use this for any transactions.
|
|
13
14
|
*/
|
|
14
15
|
pool;
|
|
16
|
+
types;
|
|
15
17
|
connectionPromises = [];
|
|
16
18
|
constructor(options, poolOptions) {
|
|
17
19
|
this.options = options;
|
|
18
20
|
this.poolOptions = poolOptions;
|
|
19
21
|
// The pool is lazy - no connections are opened until a query is performed.
|
|
20
22
|
this.pool = pgwire.connectPgWirePool(this.options, poolOptions);
|
|
23
|
+
this.types = new PostgresTypeResolver(poolOptions.registry, this.pool);
|
|
21
24
|
}
|
|
22
25
|
get connectionTag() {
|
|
23
26
|
return this.options.tag;
|
|
@@ -34,9 +37,7 @@ export class PgManager {
|
|
|
34
37
|
* @returns The Postgres server version in a parsed Semver instance
|
|
35
38
|
*/
|
|
36
39
|
async getServerVersion() {
|
|
37
|
-
|
|
38
|
-
// The result is usually of the form "16.2 (Debian 16.2-1.pgdg120+2)"
|
|
39
|
-
return semver.coerce(result.rows[0][0].split(' ')[0]);
|
|
40
|
+
return await getServerVersion(this.pool);
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
43
|
* Create a new standard connection, used for initial snapshot.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PgManager.js","sourceRoot":"","sources":["../../src/replication/PgManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"PgManager.js","sourceRoot":"","sources":["../../src/replication/PgManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,3 +4,4 @@ export type ReplicationIdentity = 'default' | 'nothing' | 'full' | 'index';
|
|
|
4
4
|
export declare function getReplicaIdColumns(relation: PgoutputRelation): storage.ColumnDescriptor[];
|
|
5
5
|
export declare function getRelId(source: PgoutputRelation): number;
|
|
6
6
|
export declare function getPgOutputRelation(source: PgoutputRelation): storage.SourceEntityDescriptor;
|
|
7
|
+
export declare function referencedColumnTypeIds(source: PgoutputRelation): number[];
|
|
@@ -25,4 +25,11 @@ export function getPgOutputRelation(source) {
|
|
|
25
25
|
replicaIdColumns: getReplicaIdColumns(source)
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
export function referencedColumnTypeIds(source) {
|
|
29
|
+
const oids = new Set();
|
|
30
|
+
for (const column of source.columns) {
|
|
31
|
+
oids.add(column.typeOid);
|
|
32
|
+
}
|
|
33
|
+
return [...oids];
|
|
34
|
+
}
|
|
28
35
|
//# sourceMappingURL=PgRelation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PgRelation.js","sourceRoot":"","sources":["../../src/replication/PgRelation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAM9E,MAAM,UAAU,mBAAmB,CAAC,QAA0B;IAC5D,IAAI,QAAQ,CAAC,eAAe,IAAI,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,OAAO,QAAQ,CAAC,OAAO;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAoC,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AACD,MAAM,UAAU,QAAQ,CAAC,MAAwB;IAC/C,8BAA8B;IAC9B,MAAM,KAAK,GAAI,MAAc,CAAC,WAAqB,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAwB;IAC1D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC;QAC1B,gBAAgB,EAAE,mBAAmB,CAAC,MAAM,CAAC;KACL,CAAC;AAC7C,CAAC"}
|
|
1
|
+
{"version":3,"file":"PgRelation.js","sourceRoot":"","sources":["../../src/replication/PgRelation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAM9E,MAAM,UAAU,mBAAmB,CAAC,QAA0B;IAC5D,IAAI,QAAQ,CAAC,eAAe,IAAI,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;SAAM,CAAC;QACN,OAAO,QAAQ,CAAC,OAAO;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAoC,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AACD,MAAM,UAAU,QAAQ,CAAC,MAAwB;IAC/C,8BAA8B;IAC9B,MAAM,KAAK,GAAI,MAAc,CAAC,WAAqB,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAwB;IAC1D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC;QAC1B,gBAAgB,EAAE,mBAAmB,CAAC,MAAM,CAAC;KACL,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAwB;IAC9D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -78,7 +78,12 @@ export declare class WalStream {
|
|
|
78
78
|
static getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteInputRow>;
|
|
79
79
|
private snapshotTableInTx;
|
|
80
80
|
private snapshotTable;
|
|
81
|
-
handleRelation(
|
|
81
|
+
handleRelation(options: {
|
|
82
|
+
batch: storage.BucketStorageBatch;
|
|
83
|
+
descriptor: SourceEntityDescriptor;
|
|
84
|
+
snapshot: boolean;
|
|
85
|
+
referencedTypeIds: number[];
|
|
86
|
+
}): Promise<SourceTable>;
|
|
82
87
|
/**
|
|
83
88
|
* Process rows that have missing TOAST values.
|
|
84
89
|
*
|
|
@@ -3,8 +3,7 @@ import { container, DatabaseConnectionError, ErrorCode, errors, logger as defaul
|
|
|
3
3
|
import { getUuidReplicaIdentityBson, RelationCache, storage } from '@powersync/service-core';
|
|
4
4
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
5
5
|
import { applyValueContext, CompatibilityContext, toSyncRulesRow } from '@powersync/service-sync-rules';
|
|
6
|
-
import
|
|
7
|
-
import { getPgOutputRelation, getRelId } from './PgRelation.js';
|
|
6
|
+
import { getPgOutputRelation, getRelId, referencedColumnTypeIds } from './PgRelation.js';
|
|
8
7
|
import { checkSourceConfiguration, checkTableRls, getReplicationIdentityColumns } from './replication-utils.js';
|
|
9
8
|
import { ReplicationMetric } from '@powersync/service-types';
|
|
10
9
|
import { ChunkedSnapshotQuery, IdSnapshotQuery, SimpleSnapshotQuery } from './SnapshotQuery.js';
|
|
@@ -101,29 +100,28 @@ export class WalStream {
|
|
|
101
100
|
}
|
|
102
101
|
let tableRows;
|
|
103
102
|
const prefix = tablePattern.isWildcard ? tablePattern.tablePrefix : undefined;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
{
|
|
104
|
+
let query = `
|
|
105
|
+
SELECT
|
|
106
|
+
c.oid AS relid,
|
|
107
|
+
c.relname AS table_name,
|
|
108
|
+
(SELECT
|
|
109
|
+
json_agg(DISTINCT a.atttypid)
|
|
110
|
+
FROM pg_attribute a
|
|
111
|
+
WHERE a.attnum > 0 AND NOT a.attisdropped AND a.attrelid = c.oid)
|
|
112
|
+
AS column_types
|
|
107
113
|
FROM pg_class c
|
|
108
114
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
109
115
|
WHERE n.nspname = $1
|
|
110
|
-
AND c.relkind = 'r'
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
tableRows = pgwire.pgwireRows(result);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
116
|
+
AND c.relkind = 'r'`;
|
|
117
|
+
if (tablePattern.isWildcard) {
|
|
118
|
+
query += ' AND c.relname LIKE $2';
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
query += ' AND c.relname = $2';
|
|
122
|
+
}
|
|
120
123
|
const result = await db.query({
|
|
121
|
-
statement:
|
|
122
|
-
FROM pg_class c
|
|
123
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
124
|
-
WHERE n.nspname = $1
|
|
125
|
-
AND c.relkind = 'r'
|
|
126
|
-
AND c.relname = $2`,
|
|
124
|
+
statement: query,
|
|
127
125
|
params: [
|
|
128
126
|
{ type: 'varchar', value: schema },
|
|
129
127
|
{ type: 'varchar', value: tablePattern.tablePattern }
|
|
@@ -165,12 +163,18 @@ export class WalStream {
|
|
|
165
163
|
this.logger.warn(`Could not check RLS access for ${tablePattern.schema}.${name}`, e);
|
|
166
164
|
}
|
|
167
165
|
const cresult = await getReplicationIdentityColumns(db, relid);
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
166
|
+
const columnTypes = JSON.parse(row.column_types).map((e) => Number(e));
|
|
167
|
+
const table = await this.handleRelation({
|
|
168
|
+
batch,
|
|
169
|
+
descriptor: {
|
|
170
|
+
name,
|
|
171
|
+
schema,
|
|
172
|
+
objectId: relid,
|
|
173
|
+
replicaIdColumns: cresult.replicationColumns
|
|
174
|
+
},
|
|
175
|
+
snapshot: false,
|
|
176
|
+
referencedTypeIds: columnTypes
|
|
177
|
+
});
|
|
174
178
|
result.push(table);
|
|
175
179
|
}
|
|
176
180
|
return result;
|
|
@@ -534,7 +538,8 @@ WHERE oid = $1::regclass`,
|
|
|
534
538
|
}
|
|
535
539
|
}
|
|
536
540
|
}
|
|
537
|
-
async handleRelation(
|
|
541
|
+
async handleRelation(options) {
|
|
542
|
+
const { batch, descriptor, snapshot, referencedTypeIds } = options;
|
|
538
543
|
if (!descriptor.objectId && typeof descriptor.objectId != 'number') {
|
|
539
544
|
throw new ReplicationAssertionError(`objectId expected, got ${typeof descriptor.objectId}`);
|
|
540
545
|
}
|
|
@@ -548,6 +553,8 @@ WHERE oid = $1::regclass`,
|
|
|
548
553
|
this.relationCache.update(result.table);
|
|
549
554
|
// Drop conflicting tables. This includes for example renamed tables.
|
|
550
555
|
await batch.drop(result.dropTables);
|
|
556
|
+
// Ensure we have a description for custom types referenced in the table.
|
|
557
|
+
await this.connections.types.fetchTypes(referencedTypeIds);
|
|
551
558
|
// Snapshot if:
|
|
552
559
|
// 1. Snapshot is requested (false for initial snapshot, since that process handles it elsewhere)
|
|
553
560
|
// 2. Snapshot is not already done, AND:
|
|
@@ -625,7 +632,7 @@ WHERE oid = $1::regclass`,
|
|
|
625
632
|
}
|
|
626
633
|
if (msg.tag == 'insert') {
|
|
627
634
|
this.metrics.getCounter(ReplicationMetric.ROWS_REPLICATED).add(1);
|
|
628
|
-
const baseRecord =
|
|
635
|
+
const baseRecord = this.connections.types.constructAfterRecord(msg);
|
|
629
636
|
return await batch.save({
|
|
630
637
|
tag: storage.SaveOperationTag.INSERT,
|
|
631
638
|
sourceTable: table,
|
|
@@ -639,8 +646,8 @@ WHERE oid = $1::regclass`,
|
|
|
639
646
|
this.metrics.getCounter(ReplicationMetric.ROWS_REPLICATED).add(1);
|
|
640
647
|
// "before" may be null if the replica id columns are unchanged
|
|
641
648
|
// It's fine to treat that the same as an insert.
|
|
642
|
-
const before =
|
|
643
|
-
const after =
|
|
649
|
+
const before = this.connections.types.constructBeforeRecord(msg);
|
|
650
|
+
const after = this.connections.types.constructAfterRecord(msg);
|
|
644
651
|
return await batch.save({
|
|
645
652
|
tag: storage.SaveOperationTag.UPDATE,
|
|
646
653
|
sourceTable: table,
|
|
@@ -652,7 +659,7 @@ WHERE oid = $1::regclass`,
|
|
|
652
659
|
}
|
|
653
660
|
else if (msg.tag == 'delete') {
|
|
654
661
|
this.metrics.getCounter(ReplicationMetric.ROWS_REPLICATED).add(1);
|
|
655
|
-
const before =
|
|
662
|
+
const before = this.connections.types.constructBeforeRecord(msg);
|
|
656
663
|
return await batch.save({
|
|
657
664
|
tag: storage.SaveOperationTag.DELETE,
|
|
658
665
|
sourceTable: table,
|
|
@@ -776,7 +783,12 @@ WHERE oid = $1::regclass`,
|
|
|
776
783
|
const lastCommit = messages.findLast((msg) => msg.tag == 'commit');
|
|
777
784
|
for (const msg of messages) {
|
|
778
785
|
if (msg.tag == 'relation') {
|
|
779
|
-
await this.handleRelation(
|
|
786
|
+
await this.handleRelation({
|
|
787
|
+
batch,
|
|
788
|
+
descriptor: getPgOutputRelation(msg),
|
|
789
|
+
snapshot: true,
|
|
790
|
+
referencedTypeIds: referencedColumnTypeIds(msg)
|
|
791
|
+
});
|
|
780
792
|
}
|
|
781
793
|
else if (msg.tag == 'begin') {
|
|
782
794
|
// This may span multiple transactions in the same chunk, or even across chunks.
|