masterrecord 0.2.36 → 0.3.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.
Files changed (38) hide show
  1. package/.claude/settings.local.json +20 -1
  2. package/Entity/entityModel.js +6 -0
  3. package/Entity/entityTrackerModel.js +20 -3
  4. package/Entity/fieldTransformer.js +266 -0
  5. package/Migrations/migrationMySQLQuery.js +145 -1
  6. package/Migrations/migrationPostgresQuery.js +402 -0
  7. package/Migrations/migrationSQLiteQuery.js +145 -1
  8. package/Migrations/schema.js +131 -28
  9. package/QueryLanguage/queryMethods.js +193 -15
  10. package/QueryLanguage/queryParameters.js +136 -0
  11. package/QueryLanguage/queryScript.js +13 -4
  12. package/SQLLiteEngine.js +331 -20
  13. package/context.js +91 -14
  14. package/docs/INCLUDES_CLARIFICATION.md +202 -0
  15. package/docs/METHODS_REFERENCE.md +184 -0
  16. package/docs/MIGRATIONS_GUIDE.md +699 -0
  17. package/docs/POSTGRESQL_SETUP.md +415 -0
  18. package/examples/jsonArrayTransformer.js +215 -0
  19. package/mySQLEngine.js +273 -17
  20. package/package.json +3 -3
  21. package/postgresEngine.js +600 -483
  22. package/postgresSyncConnect.js +209 -0
  23. package/readme.md +1046 -416
  24. package/test/anyCommaStringTest.js +237 -0
  25. package/test/anyMethodTest.js +176 -0
  26. package/test/findByIdTest.js +227 -0
  27. package/test/includesFeatureTest.js +183 -0
  28. package/test/includesTransformTest.js +110 -0
  29. package/test/newMethodTest.js +330 -0
  30. package/test/newMethodUnitTest.js +320 -0
  31. package/test/parameterizedPlaceholderTest.js +159 -0
  32. package/test/postgresEngineTest.js +463 -0
  33. package/test/postgresIntegrationTest.js +381 -0
  34. package/test/securityTest.js +268 -0
  35. package/test/singleDollarPlaceholderTest.js +238 -0
  36. package/test/transformerTest.js +287 -0
  37. package/test/verifyFindById.js +169 -0
  38. package/test/verifyNewMethod.js +191 -0
@@ -0,0 +1,209 @@
1
+ // Version 1.0.0 - PostgreSQL connection helper for pg 8.16.3
2
+ const { Pool } = require('pg');
3
+ const postgresEngine = require('./postgresEngine');
4
+
5
+ /**
6
+ * PostgreSQL connection manager for MasterRecord
7
+ * Uses pg library with connection pooling
8
+ */
9
+ class PostgresSyncConnect {
10
+ constructor() {
11
+ this.pool = null;
12
+ this.engine = null;
13
+ this.config = null;
14
+ }
15
+
16
+ /**
17
+ * Initialize PostgreSQL connection
18
+ * @param {Object} config - Connection configuration
19
+ * @param {string} config.host - Database host (default: 'localhost')
20
+ * @param {number} config.port - Database port (default: 5432)
21
+ * @param {string} config.database - Database name (required)
22
+ * @param {string} config.user - Database user (required)
23
+ * @param {string} config.password - Database password (required)
24
+ * @param {number} config.max - Max pool size (default: 20)
25
+ * @param {number} config.idleTimeoutMillis - Idle timeout (default: 30000)
26
+ * @param {number} config.connectionTimeoutMillis - Connection timeout (default: 2000)
27
+ */
28
+ async connect(config) {
29
+ if (!config.database) {
30
+ throw new Error('PostgreSQL: database name is required');
31
+ }
32
+ if (!config.user) {
33
+ throw new Error('PostgreSQL: user is required');
34
+ }
35
+ if (!config.password) {
36
+ throw new Error('PostgreSQL: password is required');
37
+ }
38
+
39
+ this.config = {
40
+ host: config.host || 'localhost',
41
+ port: config.port || 5432,
42
+ database: config.database,
43
+ user: config.user,
44
+ password: config.password,
45
+ max: config.max || 20,
46
+ idleTimeoutMillis: config.idleTimeoutMillis || 30000,
47
+ connectionTimeoutMillis: config.connectionTimeoutMillis || 2000,
48
+ ssl: config.ssl || false,
49
+ // Enable better error messages
50
+ application_name: 'MasterRecord',
51
+ };
52
+
53
+ // Create connection pool
54
+ this.pool = new Pool(this.config);
55
+
56
+ // Test connection
57
+ try {
58
+ const client = await this.pool.connect();
59
+ console.log(`PostgreSQL connected to ${config.database} at ${config.host}:${config.port}`);
60
+ client.release();
61
+ } catch (err) {
62
+ console.error('PostgreSQL connection failed:', err.message);
63
+ throw err;
64
+ }
65
+
66
+ // Initialize engine
67
+ this.engine = new postgresEngine();
68
+ this.engine.setDB(this.pool, 'postgres');
69
+
70
+ // Set up error handlers
71
+ this.pool.on('error', (err, client) => {
72
+ console.error('Unexpected PostgreSQL error:', err);
73
+ });
74
+
75
+ this.pool.on('connect', (client) => {
76
+ console.log('New PostgreSQL client connected');
77
+ });
78
+
79
+ return this.pool;
80
+ }
81
+
82
+ /**
83
+ * Get the SQL engine instance
84
+ */
85
+ getEngine() {
86
+ if (!this.engine) {
87
+ throw new Error('PostgreSQL not connected. Call connect() first.');
88
+ }
89
+ return this.engine;
90
+ }
91
+
92
+ /**
93
+ * Get the connection pool
94
+ */
95
+ getPool() {
96
+ if (!this.pool) {
97
+ throw new Error('PostgreSQL not connected. Call connect() first.');
98
+ }
99
+ return this.pool;
100
+ }
101
+
102
+ /**
103
+ * Execute raw SQL query
104
+ * @param {string} query - SQL query with $1, $2 placeholders
105
+ * @param {Array} params - Query parameters
106
+ */
107
+ async query(query, params = []) {
108
+ if (!this.pool) {
109
+ throw new Error('PostgreSQL not connected. Call connect() first.');
110
+ }
111
+
112
+ try {
113
+ const result = await this.pool.query(query, params);
114
+ return result;
115
+ } catch (err) {
116
+ console.error('PostgreSQL query error:', err);
117
+ throw err;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Execute query in a transaction
123
+ * @param {Function} callback - Async function that receives client
124
+ */
125
+ async transaction(callback) {
126
+ if (!this.pool) {
127
+ throw new Error('PostgreSQL not connected. Call connect() first.');
128
+ }
129
+
130
+ const client = await this.pool.connect();
131
+
132
+ try {
133
+ await client.query('BEGIN');
134
+ const result = await callback(client);
135
+ await client.query('COMMIT');
136
+ return result;
137
+ } catch (err) {
138
+ await client.query('ROLLBACK');
139
+ console.error('Transaction error:', err);
140
+ throw err;
141
+ } finally {
142
+ client.release();
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Check if connected
148
+ */
149
+ isConnected() {
150
+ return this.pool !== null;
151
+ }
152
+
153
+ /**
154
+ * Get connection info
155
+ */
156
+ getConnectionInfo() {
157
+ if (!this.config) {
158
+ return null;
159
+ }
160
+
161
+ return {
162
+ host: this.config.host,
163
+ port: this.config.port,
164
+ database: this.config.database,
165
+ user: this.config.user,
166
+ maxConnections: this.config.max
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Close connection pool
172
+ */
173
+ async close() {
174
+ if (this.pool) {
175
+ await this.pool.end();
176
+ console.log('PostgreSQL pool closed');
177
+ this.pool = null;
178
+ this.engine = null;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Health check
184
+ */
185
+ async healthCheck() {
186
+ if (!this.pool) {
187
+ return { healthy: false, error: 'Not connected' };
188
+ }
189
+
190
+ try {
191
+ const result = await this.pool.query('SELECT NOW() as time, version() as version');
192
+ return {
193
+ healthy: true,
194
+ serverTime: result.rows[0].time,
195
+ version: result.rows[0].version,
196
+ poolSize: this.pool.totalCount,
197
+ idleCount: this.pool.idleCount,
198
+ waitingCount: this.pool.waitingCount
199
+ };
200
+ } catch (err) {
201
+ return {
202
+ healthy: false,
203
+ error: err.message
204
+ };
205
+ }
206
+ }
207
+ }
208
+
209
+ module.exports = PostgresSyncConnect;