@idpass/data-collect-core / PostgresEntityStorageAdapter
Class: PostgresEntityStorageAdapter
Defined in: storage/PostgresEntityStorageAdapter.ts:141
PostgreSQL implementation of the EntityStorageAdapter for server-side entity persistence.
This adapter provides scalable, ACID-compliant entity storage using PostgreSQL with advanced features like JSONB support, full-text search, and multi-tenant isolation. It's designed for production server deployments requiring robust data persistence.
Key features:
- ACID Transactions: Full PostgreSQL transaction support for data consistency
- JSONB Storage: Efficient JSON storage with native PostgreSQL indexing and querying
- Multi-Tenant Support: Complete tenant isolation using tenant_id partitioning
- Advanced Search: Rich query capabilities with JSONB operators and regex support
- Connection Pooling: Efficient connection management for high-concurrency scenarios
- Scalable Architecture: Designed for production workloads with proper indexing
- Duplicate Detection: Optimized duplicate tracking with compound primary keys
Architecture:
- Uses PostgreSQL connection pooling for performance and scalability
- Stores entities as JSONB documents for flexible schema evolution
- Implements tenant isolation at the database level
- Provides optimized queries with proper indexing strategies
- Supports advanced search operations using PostgreSQL's JSONB capabilities
Database Schema:
-- Main entities table
CREATE TABLE entities (
id TEXT,
guid TEXT,
initial JSONB, -- Original entity state
modified JSONB, -- Current entity state
sync_level TEXT, -- Synchronization status
last_updated TIMESTAMP, -- Last modification timestamp
tenant_id TEXT, -- Tenant isolation
PRIMARY KEY (id, tenant_id),
UNIQUE (guid, tenant_id)
);
-- Potential duplicates tracking
CREATE TABLE potential_duplicates (
entity_guid TEXT,
duplicate_guid TEXT,
tenant_id TEXT,
PRIMARY KEY (entity_guid, duplicate_guid, tenant_id)
);
Examples
Basic server setup:
const adapter = new PostgresEntityStorageAdapter(
'postgresql://user:pass@localhost:5432/datacollect',
'tenant-123'
);
await adapter.initialize();
// Save an entity
const entityPair: EntityPair = {
guid: 'person-456',
initial: originalEntity,
modified: updatedEntity
};
await adapter.saveEntity(entityPair);
Advanced search with JSONB:
// Search for adults with complex criteria
const adults = await adapter.searchEntities([
{ "data.age": { $gte: 18 } }, // Age >= 18
{ "data.status": "active" }, // Exact string match
{ "data.name": { $regex: "john" } }, // Case-insensitive regex
{ "data.verified": true } // Boolean match
]);
// Search with numeric ranges
const middleAged = await adapter.searchEntities([
{ "data.age": { $gte: 30 } },
{ "data.age": { $lte: 65 } }
]);
Multi-tenant deployment:
// Tenant-specific adapters
const orgAAdapter = new PostgresEntityStorageAdapter(connectionString, 'org-a');
const orgBAdapter = new PostgresEntityStorageAdapter(connectionString, 'org-b');
// Each adapter operates on isolated data
await orgAAdapter.initialize();
await orgBAdapter.initialize();
// Data is completely isolated between tenants
await orgAAdapter.saveEntity(entityForOrgA);
await orgBAdapter.saveEntity(entityForOrgB);
Production connection configuration:
const adapter = new PostgresEntityStorageAdapter(
'postgresql://datacollect_user:secure_pass@db.example.com:5432/datacollect_prod?sslmode=require',
process.env.TENANT_ID
);
// Initialize with proper error handling
try {
await adapter.initialize();
console.log('Database initialized successfully');
} catch (error) {
console.error('Database initialization failed:', error);
process.exit(1);
}
Implements
Constructors
Constructor
new PostgresEntityStorageAdapter(
connectionString,tenantId?):PostgresEntityStorageAdapter
Defined in: storage/PostgresEntityStorageAdapter.ts:165
Creates a new PostgresEntityStorageAdapter instance.
Parameters
connectionString
string
PostgreSQL connection string with credentials and database info.
tenantId?
string
Optional tenant identifier for multi-tenant isolation (defaults to "default").
Returns
PostgresEntityStorageAdapter
Example
// Local development
const adapter = new PostgresEntityStorageAdapter(
'postgresql://user:pass@localhost:5432/datacollect_dev'
);
// Production with tenant isolation
const prodAdapter = new PostgresEntityStorageAdapter(
'postgresql://datacollect_user:secure_pass@db.prod.com:5432/datacollect?sslmode=require',
'tenant-org-123'
);
Methods
closeConnection()
closeConnection():
Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:189
Closes all connections in the PostgreSQL connection pool.
Should be called during application shutdown to ensure graceful cleanup of database connections.
Returns
Promise<void>
A Promise that resolves when the connection is closed.
Example
// Application shutdown handler
process.on('SIGTERM', async () => {
await adapter.closeConnection();
console.log('Database connections closed');
process.exit(0);
});
Implementation of
EntityStorageAdapter.closeConnection
initialize()
initialize():
Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:217
Initializes the PostgreSQL database with required tables and schemas.
Creates entities table with JSONB storage, potential_duplicates table for duplicate detection,
and sets up proper indexing and constraints for multi-tenant isolation.
This method is idempotent and safe to call multiple times.
Returns
Promise<void>
A Promise that resolves when the database is successfully initialized.
Throws
When database connection fails or table creation fails.
Example
const adapter = new PostgresEntityStorageAdapter(connectionString, tenantId);
try {
await adapter.initialize();
console.log('Database schema initialized');
} catch (error) {
console.error('Failed to initialize database:', error);
throw error;
}
Implementation of
EntityStorageAdapter.initialize
getAllEntities()
getAllEntities():
Promise<EntityPair[]>
Defined in: storage/PostgresEntityStorageAdapter.ts:252
Retrieves all entity pairs for the current tenant.
Returns
Promise<EntityPair[]>
A Promise that resolves with an array of EntityPair objects.
Throws
If the database query fails.
Implementation of
EntityStorageAdapter.getAllEntities
searchEntities()
searchEntities(
criteria):Promise<EntityPair[]>
Defined in: storage/PostgresEntityStorageAdapter.ts:304
Searches entities using advanced PostgreSQL JSONB query capabilities.
Supports rich query operators optimized for PostgreSQL:
$gt,$gte: Greater than, greater than or equal (numeric)$lt,$lte: Less than, less than or equal (numeric)$eq: Exact equality (numeric)$regex: Case-insensitive regex matching using PostgreSQL ~* operator- String values: Case-insensitive exact matching
- Boolean values: Direct boolean comparison
- Numeric values: Exact numeric comparison
All searches examine both initial and modified entity states for comprehensive results.
Parameters
criteria
Array of search criteria objects.
Returns
Promise<EntityPair[]>
A Promise that resolves with an array of entity pairs matching all criteria.
Throws
If the database query fails.
Example
// Complex multi-criteria search
const results = await adapter.searchEntities([
{ "data.age": { $gte: 21 } }, // Adults over 21
{ "data.age": { $lt: 65 } }, // Under retirement age
{ "data.status": "active" }, // Active status
{ "data.name": { $regex: "smith" } }, // Name contains "smith"
{ "data.verified": true } // Verified accounts
]);
// Geographic search
const localUsers = await adapter.searchEntities([
{ "data.address.city": "Boston" },
{ "data.address.state": "MA" }
]);
Implementation of
EntityStorageAdapter.searchEntities
saveEntity()
saveEntity(
entity):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:361
Saves an EntityPair to the entity store.
If an entity with the same GUID and tenant ID already exists, it will be updated.
Parameters
entity
The EntityPair object to save.
Returns
Promise<void>
A Promise that resolves when the entity is successfully saved.
Throws
If the database operation fails.
Implementation of
EntityStorageAdapter.saveEntity
getEntity()
getEntity(
id):Promise<EntityPair|null>
Defined in: storage/PostgresEntityStorageAdapter.ts:382
Retrieves an entity by its internal ID.
Parameters
id
string
The internal ID of the entity.
Returns
Promise<EntityPair | null>
A Promise that resolves with the EntityPair if found, or null otherwise.
Throws
If the database query fails.
Implementation of
EntityStorageAdapter.getEntity
getAllEntityData()
getAllEntityData():
Promise<EntityPair[]>
Defined in: storage/PostgresEntityStorageAdapter.ts:409
Retrieves all entity data. This is an alias for getAllEntities.
Returns
Promise<EntityPair[]>
A Promise that resolves with an array of all EntityPair objects.
Throws
If the database query fails.
getModifiedEntitiesSince()
getModifiedEntitiesSince(
timestamp):Promise<EntityPair[]>
Defined in: storage/PostgresEntityStorageAdapter.ts:420
Retrieves entities that have been modified since a specific timestamp.
Parameters
timestamp
string
The ISO 8601 timestamp string from which to retrieve modified entities.
Returns
Promise<EntityPair[]>
A Promise that resolves with an array of EntityPair objects modified after the timestamp.
Throws
If the database query fails.
markEntityAsSynced()
markEntityAsSynced(
id):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:444
Marks an entity as synced by updating its sync_level to "SYNCED" and last_updated timestamp.
Parameters
id
string
The internal ID of the entity to mark as synced.
Returns
Promise<void>
A Promise that resolves when the entity's sync status is updated.
Throws
If the database update fails.
deleteEntity()
deleteEntity(
id):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:467
Deletes an entity from the store by its internal ID.
Also deletes any associated potential duplicate records.
Parameters
id
string
The internal ID of the entity to delete.
Returns
Promise<void>
A Promise that resolves when the entity and its duplicates are deleted.
Throws
If the database deletion fails.
Implementation of
EntityStorageAdapter.deleteEntity
getEntityByExternalId()
getEntityByExternalId(
externalId):Promise<EntityPair|null>
Defined in: storage/PostgresEntityStorageAdapter.ts:489
Retrieves an entity by its external ID.
Searches both initial and modified states for the externalId field.
Parameters
externalId
string
The external ID of the entity to retrieve.
Returns
Promise<EntityPair | null>
A Promise that resolves with the EntityPair if found, or null otherwise.
Throws
If the database query fails.
Implementation of
EntityStorageAdapter.getEntityByExternalId
setExternalId()
setExternalId(
guid,externalId):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:520
Sets or updates the externalId for an entity.
Updates the externalId within the modified JSONB data of the entity.
Parameters
guid
string
The GUID of the entity to update.
externalId
string
The new external ID to set.
Returns
Promise<void>
A Promise that resolves when the externalId is successfully set.
Throws
If the database update fails.
getPotentialDuplicates()
getPotentialDuplicates():
Promise<object[]>
Defined in: storage/PostgresEntityStorageAdapter.ts:542
Retrieves all potential duplicate entity pairs for the current tenant.
Returns
Promise<object[]>
A Promise that resolves with an array of objects containing entityGuid and duplicateGuid.
Throws
If the database query fails.
Implementation of
EntityStorageAdapter.getPotentialDuplicates
savePotentialDuplicates()
savePotentialDuplicates(
duplicates):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:567
Saves an array of potential duplicate entity pairs.
Uses ON CONFLICT DO NOTHING to prevent duplicate entries if a pair already exists.
Parameters
duplicates
object[]
An array of objects, each containing entityGuid and duplicateGuid.
Returns
Promise<void>
A Promise that resolves when the potential duplicates are saved.
Throws
If the database transaction fails.
Implementation of
EntityStorageAdapter.savePotentialDuplicates
resolvePotentialDuplicates()
resolvePotentialDuplicates(
duplicates):Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:593
Resolves (deletes) an array of potential duplicate entity pairs.
Parameters
duplicates
object[]
An array of objects, each containing entityGuid and duplicateGuid of the duplicates to resolve.
Returns
Promise<void>
A Promise that resolves when the potential duplicates are removed.
Throws
If the database deletion fails.
Implementation of
EntityStorageAdapter.resolvePotentialDuplicates
clearStore()
clearStore():
Promise<void>
Defined in: storage/PostgresEntityStorageAdapter.ts:611
Clears all entities and potential duplicates for the current tenant from the store.
Returns
Promise<void>
A Promise that resolves when all data is cleared.
Throws
If the database deletion fails.