meadow-connection-postgresql 1.0.0 → 1.0.1
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/README.md +133 -0
- package/docker-compose.yml +20 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +96 -0
- package/docs/_cover.md +17 -0
- package/docs/_sidebar.md +33 -0
- package/docs/_topbar.md +5 -0
- package/docs/api/connect.md +100 -0
- package/docs/api/connectAsync.md +92 -0
- package/docs/api/createTable.md +116 -0
- package/docs/api/createTables.md +128 -0
- package/docs/api/generateCreateTableStatement.md +136 -0
- package/docs/api/generateDropTableStatement.md +71 -0
- package/docs/api/pool.md +171 -0
- package/docs/api/reference.md +112 -0
- package/docs/api.md +3 -0
- package/docs/architecture.md +168 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/index.html +39 -0
- package/docs/quickstart.md +181 -0
- package/docs/retold-catalog.json +62 -0
- package/docs/retold-keyword-index.json +4964 -0
- package/docs/schema.md +148 -0
- package/package.json +5 -2
- package/source/Meadow-Connection-PostgreSQL.js +79 -99
- package/source/Meadow-Schema-PostgreSQL.js +1038 -0
- package/start-postgresql.sh +21 -0
- package/stop-postgresql.sh +9 -0
- package/test/PostgreSQL_tests.js +865 -1
- package/test/docker-init/01-chinook-schema.sql +177 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# meadow-connection-postgresql
|
|
2
|
+
|
|
3
|
+
PostgreSQL connection service for the Meadow data access layer.
|
|
4
|
+
|
|
5
|
+
[](https://coveralls.io/github/stevenvelozo/meadow-connection-postgresql?branch=main)
|
|
6
|
+
[](https://github.com/stevenvelozo/meadow-connection-postgresql/actions)
|
|
7
|
+
[](https://www.npmjs.com/package/meadow-connection-postgresql)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Fable Service Provider** -- integrates with the Fable dependency injection ecosystem
|
|
13
|
+
- **Connection Pooling** -- managed pool via the `pg` driver's `Pool` class
|
|
14
|
+
- **SQL DDL Generation** -- produces PostgreSQL-native `CREATE TABLE` and `DROP TABLE` statements
|
|
15
|
+
- **Meadow-Compatible Settings** -- accepts both Meadow-style (`Server`, `Port`) and native `pg` property names
|
|
16
|
+
- **Quoted Identifiers** -- double-quoted table and column names for safe handling of reserved words
|
|
17
|
+
- **Auto-Connect Mode** -- optionally connect during service construction
|
|
18
|
+
- **Idempotent Schema** -- `CREATE TABLE IF NOT EXISTS` and graceful handling of duplicate table errors
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
npm install meadow-connection-postgresql
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
const libFable = require('fable');
|
|
30
|
+
const libMeadowConnectionPostgreSQL = require('meadow-connection-postgresql');
|
|
31
|
+
|
|
32
|
+
let _Fable = new libFable(
|
|
33
|
+
{
|
|
34
|
+
"PostgreSQL":
|
|
35
|
+
{
|
|
36
|
+
"Server": "localhost",
|
|
37
|
+
"Port": 5432,
|
|
38
|
+
"User": "postgres",
|
|
39
|
+
"Password": "secret",
|
|
40
|
+
"Database": "myapp"
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
_Fable.serviceManager.addAndInstantiateServiceType(
|
|
45
|
+
'MeadowPostgreSQLProvider', libMeadowConnectionPostgreSQL);
|
|
46
|
+
|
|
47
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
48
|
+
(pError, pPool) =>
|
|
49
|
+
{
|
|
50
|
+
if (pError) { return console.error(pError); }
|
|
51
|
+
|
|
52
|
+
let tmpPool = _Fable.MeadowPostgreSQLProvider.pool;
|
|
53
|
+
tmpPool.query('SELECT NOW()', (pErr, pRes) =>
|
|
54
|
+
{
|
|
55
|
+
console.log('Server time:', pRes.rows[0].now);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
Settings are read from `fable.settings.PostgreSQL`:
|
|
63
|
+
|
|
64
|
+
| Setting | Alias | Default | Description |
|
|
65
|
+
|---------|-------|---------|-------------|
|
|
66
|
+
| `Server` | `host` | -- | PostgreSQL host |
|
|
67
|
+
| `Port` | `port` | -- | PostgreSQL port |
|
|
68
|
+
| `User` | `user` | -- | Authentication username |
|
|
69
|
+
| `Password` | `password` | -- | Authentication password |
|
|
70
|
+
| `Database` | `database` | -- | Target database name |
|
|
71
|
+
| `ConnectionPoolLimit` | `max` | -- | Maximum connections in the pool |
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
| Method | Description |
|
|
76
|
+
|--------|-------------|
|
|
77
|
+
| `connect()` | Synchronous -- create `pg.Pool` instance |
|
|
78
|
+
| `connectAsync(fCallback)` | Callback-style connection (recommended) |
|
|
79
|
+
| `pool` | Getter -- returns the `pg.Pool` instance |
|
|
80
|
+
| `generateCreateTableStatement(schema)` | Generate a `CREATE TABLE` DDL string |
|
|
81
|
+
| `createTable(schema, fCallback)` | Execute `CREATE TABLE` via the pool |
|
|
82
|
+
| `createTables(schema, fCallback)` | Create multiple tables sequentially |
|
|
83
|
+
| `generateDropTableStatement(name)` | Generate a `DROP TABLE IF EXISTS` DDL string |
|
|
84
|
+
|
|
85
|
+
## Column Type Mapping
|
|
86
|
+
|
|
87
|
+
| Meadow DataType | PostgreSQL Type | Constraints |
|
|
88
|
+
|-----------------|-----------------|-------------|
|
|
89
|
+
| `ID` | `SERIAL` | `PRIMARY KEY` |
|
|
90
|
+
| `GUID` | `VARCHAR(Size)` | `DEFAULT '0xDe'` |
|
|
91
|
+
| `ForeignKey` | `INTEGER` | `NOT NULL DEFAULT 0` |
|
|
92
|
+
| `Numeric` | `INTEGER` | `NOT NULL DEFAULT 0` |
|
|
93
|
+
| `Decimal` | `DECIMAL(Size)` | -- |
|
|
94
|
+
| `String` | `VARCHAR(Size)` | `NOT NULL DEFAULT ''` |
|
|
95
|
+
| `Text` | `TEXT` | -- |
|
|
96
|
+
| `DateTime` | `TIMESTAMP` | -- |
|
|
97
|
+
| `Boolean` | `BOOLEAN` | `NOT NULL DEFAULT false` |
|
|
98
|
+
|
|
99
|
+
## Part of the Retold Framework
|
|
100
|
+
|
|
101
|
+
This module is a Meadow connector that plugs into the Retold application framework. It provides the PostgreSQL persistence layer for the Meadow data access abstraction.
|
|
102
|
+
|
|
103
|
+
## Testing
|
|
104
|
+
|
|
105
|
+
```shell
|
|
106
|
+
npm test
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Coverage:
|
|
110
|
+
|
|
111
|
+
```shell
|
|
112
|
+
npm run coverage
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Related Packages
|
|
116
|
+
|
|
117
|
+
- [meadow](https://github.com/stevenvelozo/meadow) -- Data access layer and ORM
|
|
118
|
+
- [fable](https://github.com/stevenvelozo/fable) -- Application framework and service manager
|
|
119
|
+
- [foxhound](https://github.com/stevenvelozo/foxhound) -- Query generation DSL
|
|
120
|
+
- [stricture](https://github.com/stevenvelozo/stricture) -- Schema definition and DDL tools
|
|
121
|
+
- [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) -- RESTful endpoint generation
|
|
122
|
+
- [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) -- MySQL / MariaDB connector
|
|
123
|
+
- [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) -- Microsoft SQL Server connector
|
|
124
|
+
- [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) -- SQLite connector
|
|
125
|
+
- [meadow-connection-mongodb](https://github.com/stevenvelozo/meadow-connection-mongodb) -- MongoDB connector
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
|
130
|
+
|
|
131
|
+
## Contributing
|
|
132
|
+
|
|
133
|
+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
postgresql-test:
|
|
5
|
+
image: postgres:16
|
|
6
|
+
container_name: meadow-connection-postgresql-test
|
|
7
|
+
environment:
|
|
8
|
+
POSTGRES_USER: postgres
|
|
9
|
+
POSTGRES_PASSWORD: testpassword
|
|
10
|
+
POSTGRES_DB: testdb
|
|
11
|
+
ports:
|
|
12
|
+
- "25432:5432"
|
|
13
|
+
volumes:
|
|
14
|
+
- ./test/docker-init:/docker-entrypoint-initdb.d
|
|
15
|
+
healthcheck:
|
|
16
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
17
|
+
interval: 5s
|
|
18
|
+
timeout: 5s
|
|
19
|
+
retries: 20
|
|
20
|
+
start_period: 10s
|
package/docs/.nojekyll
ADDED
|
File without changes
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# meadow-connection-postgresql
|
|
2
|
+
|
|
3
|
+
PostgreSQL connection service for the Meadow data access layer. This module provides connection pool management, SQL DDL generation, and table creation for applications using PostgreSQL as their persistence store.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const libMeadowConnectionPostgreSQL = require('meadow-connection-postgresql');
|
|
10
|
+
|
|
11
|
+
// 1. Create a Fable instance with PostgreSQL settings
|
|
12
|
+
let _Fable = new libFable(
|
|
13
|
+
{
|
|
14
|
+
"PostgreSQL":
|
|
15
|
+
{
|
|
16
|
+
"Server": "localhost",
|
|
17
|
+
"Port": 5432,
|
|
18
|
+
"User": "postgres",
|
|
19
|
+
"Password": "secret",
|
|
20
|
+
"Database": "myapp",
|
|
21
|
+
"ConnectionPoolLimit": 20
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// 2. Register and instantiate the service
|
|
26
|
+
_Fable.serviceManager.addAndInstantiateServiceType(
|
|
27
|
+
'MeadowPostgreSQLProvider', libMeadowConnectionPostgreSQL);
|
|
28
|
+
|
|
29
|
+
// 3. Connect
|
|
30
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
31
|
+
(pError, pPool) =>
|
|
32
|
+
{
|
|
33
|
+
if (pError) { return console.error(pError); }
|
|
34
|
+
|
|
35
|
+
// 4. Use the pool
|
|
36
|
+
let tmpPool = _Fable.MeadowPostgreSQLProvider.pool;
|
|
37
|
+
tmpPool.query('SELECT NOW()', (pErr, pRes) =>
|
|
38
|
+
{
|
|
39
|
+
console.log('Server time:', pRes.rows[0].now);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
Settings are read from `fable.settings.PostgreSQL`. Both Meadow-style names and native `pg` driver names are supported:
|
|
47
|
+
|
|
48
|
+
| Setting | Alias | Description |
|
|
49
|
+
|---------|-------|-------------|
|
|
50
|
+
| `Server` | `host` | PostgreSQL hostname or IP |
|
|
51
|
+
| `Port` | `port` | PostgreSQL port |
|
|
52
|
+
| `User` | `user` | Authentication username |
|
|
53
|
+
| `Password` | `password` | Authentication password |
|
|
54
|
+
| `Database` | `database` | Target database name |
|
|
55
|
+
| `ConnectionPoolLimit` | `max` | Maximum connections in the pool |
|
|
56
|
+
|
|
57
|
+
## How It Fits
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Application
|
|
61
|
+
|
|
|
62
|
+
v
|
|
63
|
+
Meadow (ORM)
|
|
64
|
+
|
|
|
65
|
+
v
|
|
66
|
+
FoxHound (Query Dialect)
|
|
67
|
+
|
|
|
68
|
+
v
|
|
69
|
+
meadow-connection-postgresql <-- this module
|
|
70
|
+
|
|
|
71
|
+
v
|
|
72
|
+
pg (node-postgres)
|
|
73
|
+
|
|
|
74
|
+
v
|
|
75
|
+
PostgreSQL Server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Learn More
|
|
79
|
+
|
|
80
|
+
- [Quickstart Guide](quickstart.md) -- step-by-step setup
|
|
81
|
+
- [Architecture](architecture.md) -- connection lifecycle and design diagrams
|
|
82
|
+
- [Schema & Column Types](schema.md) -- DDL generation and type mapping
|
|
83
|
+
- [API Reference](api/reference.md) -- complete method documentation
|
|
84
|
+
|
|
85
|
+
## Companion Modules
|
|
86
|
+
|
|
87
|
+
| Module | Purpose |
|
|
88
|
+
|--------|---------|
|
|
89
|
+
| [meadow](https://github.com/stevenvelozo/meadow) | Data access layer and ORM |
|
|
90
|
+
| [foxhound](https://github.com/stevenvelozo/foxhound) | Query generation DSL |
|
|
91
|
+
| [stricture](https://github.com/stevenvelozo/stricture) | Schema definition and DDL tools |
|
|
92
|
+
| [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) | MySQL / MariaDB connector |
|
|
93
|
+
| [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) | Microsoft SQL Server connector |
|
|
94
|
+
| [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) | SQLite connector |
|
|
95
|
+
| [meadow-connection-mongodb](https://github.com/stevenvelozo/meadow-connection-mongodb) | MongoDB connector |
|
|
96
|
+
| [meadow-connection-rocksdb](https://github.com/stevenvelozo/meadow-connection-rocksdb) | RocksDB key-value connector |
|
package/docs/_cover.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# meadow-connection-postgresql
|
|
2
|
+
|
|
3
|
+
<small>v1.0.0</small>
|
|
4
|
+
|
|
5
|
+
> PostgreSQL connection service for the Meadow data access layer
|
|
6
|
+
|
|
7
|
+
- **Fable Service Provider** -- seamless dependency injection integration
|
|
8
|
+
- **Connection Pooling** -- managed pool via the `pg` driver
|
|
9
|
+
- **SQL DDL Generation** -- PostgreSQL-native `CREATE TABLE` statements
|
|
10
|
+
- **Quoted Identifiers** -- safe handling of reserved words
|
|
11
|
+
- **Meadow-Compatible Settings** -- accepts both Meadow-style and native property names
|
|
12
|
+
- **Idempotent Schema** -- safe to call on every startup
|
|
13
|
+
|
|
14
|
+
[Overview](README.md)
|
|
15
|
+
[Quickstart](quickstart.md)
|
|
16
|
+
[API Reference](api/reference.md)
|
|
17
|
+
[GitHub](https://github.com/stevenvelozo/meadow-connection-postgresql)
|
package/docs/_sidebar.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
- **Getting Started**
|
|
2
|
+
- [Overview](README.md)
|
|
3
|
+
- [Quickstart](quickstart.md)
|
|
4
|
+
|
|
5
|
+
- **Concepts**
|
|
6
|
+
- [Architecture](architecture.md)
|
|
7
|
+
- [Schema & Column Types](schema.md)
|
|
8
|
+
|
|
9
|
+
- **API Reference**
|
|
10
|
+
- [Full Reference](api/reference.md)
|
|
11
|
+
- Connection
|
|
12
|
+
- [connectAsync(fCallback)](api/connectAsync.md)
|
|
13
|
+
- [connect()](api/connect.md)
|
|
14
|
+
- Accessors
|
|
15
|
+
- [pool](api/pool.md)
|
|
16
|
+
- Schema Management
|
|
17
|
+
- [generateCreateTableStatement()](api/generateCreateTableStatement.md)
|
|
18
|
+
- [createTable()](api/createTable.md)
|
|
19
|
+
- [createTables()](api/createTables.md)
|
|
20
|
+
- [generateDropTableStatement()](api/generateDropTableStatement.md)
|
|
21
|
+
|
|
22
|
+
- **Ecosystem**
|
|
23
|
+
- [Meadow](https://github.com/stevenvelozo/meadow)
|
|
24
|
+
- [FoxHound](https://github.com/stevenvelozo/foxhound)
|
|
25
|
+
- [Stricture](https://github.com/stevenvelozo/stricture)
|
|
26
|
+
- [Fable](https://github.com/stevenvelozo/fable)
|
|
27
|
+
- Connectors
|
|
28
|
+
- [MySQL](https://github.com/stevenvelozo/meadow-connection-mysql)
|
|
29
|
+
- [MSSQL](https://github.com/stevenvelozo/meadow-connection-mssql)
|
|
30
|
+
- [SQLite](https://github.com/stevenvelozo/meadow-connection-sqlite)
|
|
31
|
+
- [MongoDB](https://github.com/stevenvelozo/meadow-connection-mongodb)
|
|
32
|
+
- [RocksDB](https://github.com/stevenvelozo/meadow-connection-rocksdb)
|
|
33
|
+
- [Dgraph](https://github.com/stevenvelozo/meadow-connection-dgraph)
|
package/docs/_topbar.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# connect()
|
|
2
|
+
|
|
3
|
+
Synchronous method that creates the `pg.Pool` connection pool instance.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
connect()
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
None.
|
|
14
|
+
|
|
15
|
+
## Return Value
|
|
16
|
+
|
|
17
|
+
None.
|
|
18
|
+
|
|
19
|
+
## Behavior
|
|
20
|
+
|
|
21
|
+
1. Builds connection settings from `this.options.PostgreSQL` (host, port, user, password, database, max)
|
|
22
|
+
2. If already connected (`this._ConnectionPool` exists), logs an error with masked password and returns
|
|
23
|
+
3. Otherwise, logs the connection details and creates a new `pg.Pool`
|
|
24
|
+
4. Sets `this.connected = true`
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
_Fable.MeadowPostgreSQLProvider.connect();
|
|
30
|
+
|
|
31
|
+
if (_Fable.MeadowPostgreSQLProvider.connected)
|
|
32
|
+
{
|
|
33
|
+
let tmpPool = _Fable.MeadowPostgreSQLProvider.pool;
|
|
34
|
+
// Use the pool
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Why Both connect() and connectAsync()?
|
|
39
|
+
|
|
40
|
+
The `pg.Pool` constructor is synchronous -- it does not open actual TCP connections until a query is issued. The `connect()` method works reliably for immediate use. However, `connectAsync()` is preferred because:
|
|
41
|
+
|
|
42
|
+
- It follows the Fable service provider convention
|
|
43
|
+
- It provides error handling via the callback
|
|
44
|
+
- It guards against missing callbacks with a warning about race conditions
|
|
45
|
+
- It is consistent with other Meadow connector APIs
|
|
46
|
+
|
|
47
|
+
## Double-Connect Protection
|
|
48
|
+
|
|
49
|
+
If `connect()` is called when already connected, it logs an error with the settings (password masked) and returns without action:
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
_Fable.MeadowPostgreSQLProvider.connect();
|
|
53
|
+
_Fable.MeadowPostgreSQLProvider.connect();
|
|
54
|
+
// Logs: "Meadow-Connection-PostgreSQL trying to connect but is already
|
|
55
|
+
// connected - skipping the generation of extra connections."
|
|
56
|
+
// Settings logged with password: '*****************'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Auto-Connect
|
|
60
|
+
|
|
61
|
+
The `connect()` method is called automatically during construction if `MeadowConnectionPostgreSQLAutoConnect` is `true`:
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
let _Fable = new libFable(
|
|
65
|
+
{
|
|
66
|
+
"PostgreSQL":
|
|
67
|
+
{
|
|
68
|
+
"Server": "localhost",
|
|
69
|
+
"Port": 5432,
|
|
70
|
+
"User": "postgres",
|
|
71
|
+
"Password": "secret",
|
|
72
|
+
"Database": "myapp"
|
|
73
|
+
},
|
|
74
|
+
"MeadowConnectionPostgreSQLAutoConnect": true
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
_Fable.serviceManager.addAndInstantiateServiceType(
|
|
78
|
+
'MeadowPostgreSQLProvider', libMeadowConnectionPostgreSQL);
|
|
79
|
+
|
|
80
|
+
// Already connected -- pool is ready
|
|
81
|
+
let tmpPool = _Fable.MeadowPostgreSQLProvider.pool;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Pool Settings
|
|
85
|
+
|
|
86
|
+
The `pg.Pool` is created with these settings from `options.PostgreSQL`:
|
|
87
|
+
|
|
88
|
+
| Setting | pg Option | Description |
|
|
89
|
+
|---------|-----------|-------------|
|
|
90
|
+
| `host` | `host` | Server hostname |
|
|
91
|
+
| `port` | `port` | Server port |
|
|
92
|
+
| `user` | `user` | Authentication user |
|
|
93
|
+
| `password` | `password` | Authentication password |
|
|
94
|
+
| `database` | `database` | Target database |
|
|
95
|
+
| `max` | `max` | Maximum pool connections |
|
|
96
|
+
|
|
97
|
+
## Related
|
|
98
|
+
|
|
99
|
+
- [connectAsync](connectAsync.md) -- Callback-style connection (recommended)
|
|
100
|
+
- [pool](pool.md) -- Access the pool after connecting
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# connectAsync(fCallback)
|
|
2
|
+
|
|
3
|
+
Callback-style connection method. Creates the `pg.Pool` instance, or returns the existing pool if already connected.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
connectAsync(fCallback)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Parameter | Type | Description |
|
|
14
|
+
|-----------|------|-------------|
|
|
15
|
+
| `fCallback` | `function` | Callback receiving `(error, pool)` |
|
|
16
|
+
|
|
17
|
+
## Return Value
|
|
18
|
+
|
|
19
|
+
Returns the result of the callback invocation.
|
|
20
|
+
|
|
21
|
+
## Behavior
|
|
22
|
+
|
|
23
|
+
1. If no callback is provided, logs an error and substitutes a no-op function
|
|
24
|
+
2. If already connected (`this._ConnectionPool` exists), calls `fCallback(null, this._ConnectionPool)` immediately
|
|
25
|
+
3. Otherwise, calls `this.connect()` to create the pool
|
|
26
|
+
4. On success: calls `fCallback(null, this._ConnectionPool)`
|
|
27
|
+
5. On error: logs the error, calls `fCallback(pError)`
|
|
28
|
+
|
|
29
|
+
## Basic Usage
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
33
|
+
(pError, pPool) =>
|
|
34
|
+
{
|
|
35
|
+
if (pError)
|
|
36
|
+
{
|
|
37
|
+
console.error('Connection failed:', pError);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log('Connected! Pool ready.');
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Idempotent Calls
|
|
45
|
+
|
|
46
|
+
Calling `connectAsync()` multiple times is safe. If already connected, the existing pool is returned without creating a new one:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// First call -- creates the pool
|
|
50
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
51
|
+
(pError, pPool) =>
|
|
52
|
+
{
|
|
53
|
+
// pPool is the pg.Pool instance
|
|
54
|
+
|
|
55
|
+
// Second call -- reuses the existing pool
|
|
56
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
57
|
+
(pError2, pPool2) =>
|
|
58
|
+
{
|
|
59
|
+
// pPool2 === pPool (same pool)
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Missing Callback
|
|
65
|
+
|
|
66
|
+
If called without a callback, a warning is logged and a no-op function is used:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Logs: "Meadow PostgreSQL connectAsync() called without a callback;
|
|
70
|
+
// this could lead to connection race conditions."
|
|
71
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
If `connect()` throws, the error is caught and passed to the callback:
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
80
|
+
(pError) =>
|
|
81
|
+
{
|
|
82
|
+
if (pError)
|
|
83
|
+
{
|
|
84
|
+
console.error('PostgreSQL connection error:', pError.message);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Related
|
|
90
|
+
|
|
91
|
+
- [connect()](connect.md) -- Synchronous connection method
|
|
92
|
+
- [pool](pool.md) -- Access the pool after connecting
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# createTable(pMeadowTableSchema, fCallback)
|
|
2
|
+
|
|
3
|
+
Generates and executes a PostgreSQL `CREATE TABLE IF NOT EXISTS` statement from a Meadow table schema. Handles existing tables gracefully.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
createTable(pMeadowTableSchema, fCallback)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
| Parameter | Type | Description |
|
|
14
|
+
|-----------|------|-------------|
|
|
15
|
+
| `pMeadowTableSchema` | `object` | Meadow table schema with `TableName` and `Columns` array |
|
|
16
|
+
| `fCallback` | `function` | Callback receiving `(error)` |
|
|
17
|
+
|
|
18
|
+
## Return Value
|
|
19
|
+
|
|
20
|
+
Returns the result of the callback invocation.
|
|
21
|
+
|
|
22
|
+
## Behavior
|
|
23
|
+
|
|
24
|
+
1. Calls `generateCreateTableStatement(pMeadowTableSchema)` to produce the DDL string
|
|
25
|
+
2. Executes the DDL via `this._ConnectionPool.query(ddl, callback)`
|
|
26
|
+
3. On success: logs info, calls `fCallback()` with no error
|
|
27
|
+
4. On error code `42P07` (duplicate_table): logs a warning, calls `fCallback()` with no error
|
|
28
|
+
5. On other errors: logs the error, calls `fCallback(pError)`
|
|
29
|
+
|
|
30
|
+
## Basic Usage
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
let tmpAnimalSchema =
|
|
34
|
+
{
|
|
35
|
+
TableName: 'Animal',
|
|
36
|
+
Columns:
|
|
37
|
+
[
|
|
38
|
+
{ Column: 'IDAnimal', DataType: 'ID' },
|
|
39
|
+
{ Column: 'GUIDAnimal', DataType: 'GUID', Size: 36 },
|
|
40
|
+
{ Column: 'Name', DataType: 'String', Size: 128 },
|
|
41
|
+
{ Column: 'Age', DataType: 'Numeric' },
|
|
42
|
+
{ Column: 'Weight', DataType: 'Decimal', Size: '10,2' }
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
_Fable.MeadowPostgreSQLProvider.createTable(tmpAnimalSchema,
|
|
47
|
+
(pError) =>
|
|
48
|
+
{
|
|
49
|
+
if (pError)
|
|
50
|
+
{
|
|
51
|
+
console.error('Table creation failed:', pError);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
console.log('Animal table ready!');
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Idempotent Execution
|
|
59
|
+
|
|
60
|
+
Table creation is idempotent through two layers of protection:
|
|
61
|
+
|
|
62
|
+
1. **`CREATE TABLE IF NOT EXISTS`** in the generated SQL
|
|
63
|
+
2. **Error code 42P07 handling** -- if PostgreSQL returns `duplicate_table`, it is logged as a warning and does not produce an error in the callback
|
|
64
|
+
|
|
65
|
+
This makes `createTable()` safe to call during application startup:
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// Safe to call every time the app starts
|
|
69
|
+
_Fable.MeadowPostgreSQLProvider.createTable(tmpAnimalSchema,
|
|
70
|
+
(pError) =>
|
|
71
|
+
{
|
|
72
|
+
// First run: table created
|
|
73
|
+
// Subsequent runs: table already exists (warning logged)
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Prerequisites
|
|
78
|
+
|
|
79
|
+
The connection must be established before calling `createTable()`:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
_Fable.MeadowPostgreSQLProvider.connectAsync(
|
|
83
|
+
(pError) =>
|
|
84
|
+
{
|
|
85
|
+
if (pError) { return; }
|
|
86
|
+
|
|
87
|
+
_Fable.MeadowPostgreSQLProvider.createTable(tmpAnimalSchema,
|
|
88
|
+
(pCreateError) =>
|
|
89
|
+
{
|
|
90
|
+
if (pCreateError) { console.error(pCreateError); }
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Error Handling
|
|
96
|
+
|
|
97
|
+
Non-duplicate errors (e.g., syntax errors, permission denied) are passed to the callback:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
_Fable.MeadowPostgreSQLProvider.createTable(tmpBadSchema,
|
|
101
|
+
(pError) =>
|
|
102
|
+
{
|
|
103
|
+
if (pError)
|
|
104
|
+
{
|
|
105
|
+
// pError.code might be '42601' (syntax error) or '42501' (insufficient privilege)
|
|
106
|
+
console.error('DDL execution failed:', pError.message);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Related
|
|
112
|
+
|
|
113
|
+
- [generateCreateTableStatement](generateCreateTableStatement.md) -- Generate DDL without executing
|
|
114
|
+
- [createTables](createTables.md) -- Create multiple tables sequentially
|
|
115
|
+
- [generateDropTableStatement](generateDropTableStatement.md) -- Generate DROP TABLE DDL
|
|
116
|
+
- [Schema & Column Types](../schema.md) -- Full type mapping reference
|