meadow-connection-sqlite 1.0.10

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Steven Velozo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # Meadow Connection SQLite
2
+
3
+ A SQLite database connection provider for the Meadow ORM. Wraps [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) as a Fable service, providing file-based database connections with WAL journal mode and DDL generation from Meadow table schemas.
4
+
5
+ [![Build Status](https://github.com/stevenvelozo/meadow-connection-sqlite/workflows/Meadow-Connection-SQLite/badge.svg)](https://github.com/stevenvelozo/meadow-connection-sqlite/actions)
6
+ [![npm version](https://badge.fury.io/js/meadow-connection-sqlite.svg)](https://badge.fury.io/js/meadow-connection-sqlite)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ---
10
+
11
+ ## Features
12
+
13
+ - **Better-SQLite3 Wrapper** - Synchronous, high-performance SQLite access via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)
14
+ - **Fable Service Provider** - Registers with a Fable instance for dependency injection, logging, and configuration
15
+ - **WAL Journal Mode** - Automatically enables Write-Ahead Logging for performance on connect
16
+ - **Schema-Driven DDL** - Generates `CREATE TABLE` statements from Meadow table schemas with support for ID, GUID, ForeignKey, Numeric, Decimal, String, Text, DateTime, and Boolean column types
17
+ - **Connection Safety** - Guards against double-connect and missing file path errors with descriptive logging
18
+ - **Direct Database Access** - Exposes the underlying `better-sqlite3` database instance via `db` getter
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install meadow-connection-sqlite
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```javascript
29
+ const libFable = require('fable');
30
+ const MeadowConnectionSQLite = require('meadow-connection-sqlite');
31
+
32
+ let fable = new libFable(
33
+ {
34
+ SQLite:
35
+ {
36
+ SQLiteFilePath: './my-database.sqlite'
37
+ }
38
+ });
39
+
40
+ let connection = fable.instantiateServiceProvider('MeadowConnectionSQLite',
41
+ {}, MeadowConnectionSQLite);
42
+
43
+ connection.connectAsync((pError, pDatabase) =>
44
+ {
45
+ if (pError)
46
+ {
47
+ console.error('Connection failed:', pError);
48
+ return;
49
+ }
50
+
51
+ // Use the better-sqlite3 database directly
52
+ let stmt = connection.db.prepare('SELECT * FROM Users WHERE id = ?');
53
+ let user = stmt.get(42);
54
+ });
55
+ ```
56
+
57
+ ## Configuration
58
+
59
+ The SQLite file path can be provided through Fable settings or the service provider options:
60
+
61
+ ### Via Fable Settings
62
+
63
+ ```javascript
64
+ let fable = new libFable(
65
+ {
66
+ SQLite:
67
+ {
68
+ SQLiteFilePath: './data/app.sqlite'
69
+ }
70
+ });
71
+ ```
72
+
73
+ ### Via Provider Options
74
+
75
+ ```javascript
76
+ let connection = fable.instantiateServiceProvider('MeadowConnectionSQLite',
77
+ {
78
+ SQLiteFilePath: './data/app.sqlite'
79
+ }, MeadowConnectionSQLite);
80
+ ```
81
+
82
+ Any additional options are passed through to the `better-sqlite3` constructor.
83
+
84
+ ## API
85
+
86
+ ### `connectAsync(fCallback)`
87
+
88
+ Open the SQLite database file and enable WAL journal mode.
89
+
90
+ | Parameter | Type | Description |
91
+ |-----------|------|-------------|
92
+ | `fCallback` | `Function` | Callback receiving `(error, database)` |
93
+
94
+ ### `connect()`
95
+
96
+ Synchronous convenience wrapper for `connectAsync` (no callback, logs a warning).
97
+
98
+ ### `db` (getter)
99
+
100
+ Returns the underlying `better-sqlite3` database instance for direct query access.
101
+
102
+ ### `SQLite` (getter)
103
+
104
+ Returns the `better-sqlite3` library module.
105
+
106
+ ### `connected` (property)
107
+
108
+ Boolean indicating whether the database connection is open.
109
+
110
+ ### `generateCreateTableStatement(pMeadowTableSchema)`
111
+
112
+ Generate a `CREATE TABLE` SQL statement from a Meadow table schema object.
113
+
114
+ | Parameter | Type | Description |
115
+ |-----------|------|-------------|
116
+ | `pMeadowTableSchema` | `Object` | Meadow table schema with `TableName` and `Columns` array |
117
+
118
+ ### `createTable(pMeadowTableSchema, fCallback)`
119
+
120
+ Execute a `CREATE TABLE` statement against the connected database.
121
+
122
+ ### `createTables(pMeadowSchema, fCallback)`
123
+
124
+ Create all tables defined in a Meadow schema object (iterates `pMeadowSchema.Tables` sequentially).
125
+
126
+ ### `generateDropTableStatement(pTableName)`
127
+
128
+ Generate a `DROP TABLE IF EXISTS` SQL statement for the given table name.
129
+
130
+ ## Column Type Mapping
131
+
132
+ | Meadow Type | SQLite Column |
133
+ |-------------|---------------|
134
+ | `ID` | `INT NOT NULL IDENTITY PRIMARY KEY` |
135
+ | `GUID` | `VARCHAR(254)` with default GUID |
136
+ | `ForeignKey` | `INT UNSIGNED NOT NULL DEFAULT 0` |
137
+ | `Numeric` | `INT NOT NULL DEFAULT 0` |
138
+ | `Decimal` | `DECIMAL(size)` |
139
+ | `String` | `VARCHAR(size) DEFAULT ''` |
140
+ | `Text` | `TEXT` |
141
+ | `DateTime` | `DATETIME` |
142
+ | `Boolean` | `TINYINT DEFAULT 0` |
143
+
144
+ ## Part of the Retold Framework
145
+
146
+ Meadow Connection SQLite is a database connector for the Meadow data access layer:
147
+
148
+ - [meadow](https://github.com/stevenvelozo/meadow) - ORM and data access framework
149
+ - [foxhound](https://github.com/stevenvelozo/foxhound) - Query DSL used by Meadow
150
+ - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition tool
151
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - RESTful endpoint generation
152
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework
153
+
154
+ ## Testing
155
+
156
+ Run the test suite:
157
+
158
+ ```bash
159
+ npm test
160
+ ```
161
+
162
+ Run with coverage:
163
+
164
+ ```bash
165
+ npm run coverage
166
+ ```
167
+
168
+ ## License
169
+
170
+ MIT - See [LICENSE](LICENSE) for details.
171
+
172
+ ## Author
173
+
174
+ Steven Velozo - [steven@velozo.com](mailto:steven@velozo.com)
@@ -0,0 +1,139 @@
1
+ /*
2
+ Exercise the create table functionality of the SQLite provider
3
+ */
4
+ /**
5
+ * @author <steven@velozo.com>
6
+ */
7
+
8
+ const libFable = require('fable');
9
+ let _Fable = new libFable(
10
+ {
11
+ "Product": "MeadowSQLiteTestBookstore",
12
+ "ProductVersion": "1.0.0",
13
+
14
+ "UUID":
15
+ {
16
+ "DataCenter": 0,
17
+ "Worker": 0
18
+ },
19
+ "LogStreams":
20
+ [
21
+ {
22
+ "streamtype": "console"
23
+ }
24
+ ],
25
+
26
+ "SQLite":
27
+ {
28
+ "server": "127.0.0.1",
29
+ "port": 3306,
30
+ "user": "sa",
31
+ "password": "1234567890abc.",
32
+ "database": "bookstore",
33
+ "ConnectionPoolLimit": 20
34
+ }
35
+ });
36
+
37
+ _Fable.log.info("Application is starting up...");
38
+
39
+ const libMeadowConnectionSQLite = require('../source/Meadow-Connection-SQLite.js');
40
+ _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
41
+ _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider',
42
+ {
43
+ // This makes the sync service still able to sync IDs.
44
+ AllowIdentityInsert: true
45
+ });
46
+
47
+ _Fable.log.info("...Creating SQL Connection pools at " + _Fable.settings.SQLite.server + "...");
48
+
49
+ _Fable.MeadowSQLiteProvider.connectAsync(
50
+ (pError, pConnectionPool) =>
51
+ {
52
+ if (pError)
53
+ {
54
+ _Fable.log.error(`Error connecting to MS SQL Database: ${pError}`);
55
+ return false;
56
+ }
57
+
58
+ const tmpTestModel = require('../retold-harness/model/json_schema/BookStore-Extended.json');
59
+
60
+ _Fable.log.info('Connection complete!');
61
+ _Fable.MeadowSQLiteProvider.createTables(tmpTestModel,
62
+ (pCreateTablesError) =>
63
+ {
64
+ _Fable.log.info('Tables created successfully');
65
+ });
66
+ });
67
+
68
+
69
+ // const libFable = require('fable');
70
+ // const libMeadowConnectionSQLite = require('../source/Meadow-Connection-SQLite.js');
71
+
72
+ // let tmpTestModel = require('../retold-harness/model/json_schema/BookStore-Extended.json');
73
+
74
+ // let _Fable = new libFable(
75
+ // {
76
+ // "Product": "MeadowSQLiteTestBookstore",
77
+ // "ProductVersion": "1.0.0",
78
+
79
+ // "UUID":
80
+ // {
81
+ // "DataCenter": 0,
82
+ // "Worker": 0
83
+ // },
84
+ // "LogStreams":
85
+ // [
86
+ // {
87
+ // "streamtype": "console"
88
+ // }
89
+ // ],
90
+
91
+ // "SQLite":
92
+ // {
93
+ // "server": "127.0.0.1",
94
+ // "port": 3306,
95
+ // "user": "sa",
96
+ // "password": "1234567890abc.",
97
+ // "database": "bookstore",
98
+ // "ConnectionPoolLimit": 20
99
+ // }
100
+ // });
101
+
102
+ // _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
103
+
104
+ // _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
105
+
106
+ // _Fable.MeadowSQLiteProvider.connectAsync(
107
+ // (pError, pConnectionPool) =>
108
+ // {
109
+ // if (pError)
110
+ // {
111
+ // _Fable.log.error(`Error connecting to MS SQL Database: ${pError}`);
112
+ // return false;
113
+ // }
114
+
115
+ // _Fable.log.info('Connection complete!');
116
+ // _Fable.MeadowSQLiteProvider.createTables(tmpTestModel,
117
+ // (pCreateTablesError) =>
118
+ // {
119
+ // _Fable.log.info('Tables created successfully');
120
+ // let tmpPreparedStatement = _Fable.MeadowSQLiteProvider.preparedStatement;
121
+ // tmpPreparedStatement.input('param', _Fable.MeadowSQLiteProvider.SQLite.Int);
122
+ // tmpPreparedStatement.prepare('SELECT * FROM Book WHERE IDBook < @param',
123
+ // (pPrepareError) =>
124
+ // {
125
+ // tmpPreparedStatement.execute({ param: 12345 },
126
+ // (pPreparedExecutionError, pPreparedResult) =>
127
+ // {
128
+ // _Fable.log.info(`Prepared statement returned...`, pPreparedResult);
129
+ // // release the connection after queries are executed
130
+ // tmpPreparedStatement.unprepare(
131
+ // (pPreparedStatementUnprepareError) =>
132
+ // {
133
+ // _Fable.log.trace(`Prepared statement unprepared.`);
134
+ // });
135
+ // })
136
+ // });
137
+ // });
138
+ // }
139
+ // );
@@ -0,0 +1,143 @@
1
+ /*
2
+ Full pipeline test for meadow-connection-sqlite:
3
+ Connect → Create Table → Insert → Read → Update → Delete → Transactions → Close
4
+ */
5
+ const libFable = require('fable');
6
+ const libMeadowConnectionSQLite = require('../source/Meadow-Connection-SQLite.js');
7
+ const libFS = require('fs');
8
+
9
+ // Clean up any leftover test database
10
+ const DB_PATH = './dist/PipelineTest.db';
11
+ if (libFS.existsSync(DB_PATH))
12
+ {
13
+ libFS.unlinkSync(DB_PATH);
14
+ }
15
+
16
+ let _Fable = new libFable(
17
+ {
18
+ "Product": "MeadowSQLitePipelineTest",
19
+ "ProductVersion": "1.0.0",
20
+ "UUID": { "DataCenter": 0, "Worker": 0 },
21
+ "LogStreams": [{ "streamtype": "console" }],
22
+ "SQLite": { "SQLiteFilePath": DB_PATH }
23
+ });
24
+
25
+ // 1. Register and instantiate the provider
26
+ _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
27
+ _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
28
+
29
+ _Fable.log.info('--- Step 1: Connect ---');
30
+ _Fable.MeadowSQLiteProvider.connectAsync(
31
+ (pError, pDatabase) =>
32
+ {
33
+ if (pError)
34
+ {
35
+ _Fable.log.error(`Connection failed: ${pError}`);
36
+ process.exit(1);
37
+ }
38
+ _Fable.log.info(`Connected: ${_Fable.MeadowSQLiteProvider.connected}`);
39
+
40
+ let tmpDB = _Fable.MeadowSQLiteProvider.db;
41
+
42
+ // 2. Create a table using SQLite-compatible SQL
43
+ _Fable.log.info('--- Step 2: Create Table ---');
44
+ tmpDB.exec(`
45
+ CREATE TABLE IF NOT EXISTS Book (
46
+ IDBook INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ GUIDBook TEXT DEFAULT '00000000-0000-0000-0000-000000000000',
48
+ Title TEXT DEFAULT '',
49
+ Author TEXT DEFAULT '',
50
+ YearPublished INTEGER DEFAULT 0,
51
+ Price REAL DEFAULT 0.0,
52
+ CreateDate TEXT DEFAULT (datetime('now')),
53
+ UpdateDate TEXT DEFAULT (datetime('now'))
54
+ )
55
+ `);
56
+ _Fable.log.info('Table "Book" created.');
57
+
58
+ // 3. Insert rows
59
+ _Fable.log.info('--- Step 3: Insert ---');
60
+ let tmpInsert = tmpDB.prepare(
61
+ `INSERT INTO Book (GUIDBook, Title, Author, YearPublished, Price) VALUES (?, ?, ?, ?, ?)`
62
+ );
63
+
64
+ let tmpResult1 = tmpInsert.run(_Fable.fable.getUUID(), 'The Hobbit', 'J.R.R. Tolkien', 1937, 12.99);
65
+ _Fable.log.info(`Inserted IDBook=${tmpResult1.lastInsertRowid}`);
66
+
67
+ let tmpResult2 = tmpInsert.run(_Fable.fable.getUUID(), 'Dune', 'Frank Herbert', 1965, 14.99);
68
+ _Fable.log.info(`Inserted IDBook=${tmpResult2.lastInsertRowid}`);
69
+
70
+ let tmpResult3 = tmpInsert.run(_Fable.fable.getUUID(), 'Neuromancer', 'William Gibson', 1984, 11.50);
71
+ _Fable.log.info(`Inserted IDBook=${tmpResult3.lastInsertRowid}`);
72
+
73
+ // 4. Read all rows
74
+ _Fable.log.info('--- Step 4: Read All ---');
75
+ let tmpAllBooks = tmpDB.prepare(`SELECT * FROM Book`).all();
76
+ _Fable.log.info(`Found ${tmpAllBooks.length} books:`);
77
+ for (let i = 0; i < tmpAllBooks.length; i++)
78
+ {
79
+ _Fable.log.info(` [${tmpAllBooks[i].IDBook}] "${tmpAllBooks[i].Title}" by ${tmpAllBooks[i].Author} (${tmpAllBooks[i].YearPublished}) - $${tmpAllBooks[i].Price}`);
80
+ }
81
+
82
+ // 5. Read single row
83
+ _Fable.log.info('--- Step 5: Read One ---');
84
+ let tmpOneBook = tmpDB.prepare(`SELECT * FROM Book WHERE IDBook = ?`).get(2);
85
+ _Fable.log.info(`Single book: "${tmpOneBook.Title}" by ${tmpOneBook.Author}`);
86
+
87
+ // 6. Update
88
+ _Fable.log.info('--- Step 6: Update ---');
89
+ let tmpUpdate = tmpDB.prepare(`UPDATE Book SET Price = ?, UpdateDate = datetime('now') WHERE IDBook = ?`);
90
+ let tmpUpdateResult = tmpUpdate.run(16.99, 2);
91
+ _Fable.log.info(`Updated ${tmpUpdateResult.changes} row(s) — Dune price is now $16.99`);
92
+
93
+ let tmpUpdatedBook = tmpDB.prepare(`SELECT * FROM Book WHERE IDBook = ?`).get(2);
94
+ _Fable.log.info(`Verified: "${tmpUpdatedBook.Title}" price = $${tmpUpdatedBook.Price}`);
95
+
96
+ // 7. Delete
97
+ _Fable.log.info('--- Step 7: Delete ---');
98
+ let tmpDelete = tmpDB.prepare(`DELETE FROM Book WHERE IDBook = ?`);
99
+ let tmpDeleteResult = tmpDelete.run(3);
100
+ _Fable.log.info(`Deleted ${tmpDeleteResult.changes} row(s) — Neuromancer removed`);
101
+
102
+ let tmpRemainingBooks = tmpDB.prepare(`SELECT * FROM Book`).all();
103
+ _Fable.log.info(`Remaining books: ${tmpRemainingBooks.length}`);
104
+
105
+ // 8. Transaction
106
+ _Fable.log.info('--- Step 8: Transaction ---');
107
+ let tmpBulkInsert = tmpDB.transaction(
108
+ (pBooks) =>
109
+ {
110
+ let tmpBulkStmt = tmpDB.prepare(
111
+ `INSERT INTO Book (GUIDBook, Title, Author, YearPublished, Price) VALUES (?, ?, ?, ?, ?)`
112
+ );
113
+ for (let tmpBook of pBooks)
114
+ {
115
+ tmpBulkStmt.run(tmpBook.GUID, tmpBook.Title, tmpBook.Author, tmpBook.Year, tmpBook.Price);
116
+ }
117
+ });
118
+
119
+ tmpBulkInsert(
120
+ [
121
+ { GUID: _Fable.fable.getUUID(), Title: 'Snow Crash', Author: 'Neal Stephenson', Year: 1992, Price: 13.99 },
122
+ { GUID: _Fable.fable.getUUID(), Title: 'Hyperion', Author: 'Dan Simmons', Year: 1989, Price: 15.50 },
123
+ { GUID: _Fable.fable.getUUID(), Title: 'Foundation', Author: 'Isaac Asimov', Year: 1951, Price: 10.99 }
124
+ ]);
125
+ _Fable.log.info('Bulk insert (3 books) committed in a single transaction.');
126
+
127
+ let tmpFinalBooks = tmpDB.prepare(`SELECT * FROM Book ORDER BY IDBook`).all();
128
+ _Fable.log.info(`Final book count: ${tmpFinalBooks.length}`);
129
+ for (let i = 0; i < tmpFinalBooks.length; i++)
130
+ {
131
+ _Fable.log.info(` [${tmpFinalBooks[i].IDBook}] "${tmpFinalBooks[i].Title}" by ${tmpFinalBooks[i].Author} ($${tmpFinalBooks[i].Price})`);
132
+ }
133
+
134
+ // 9. Aggregate query
135
+ _Fable.log.info('--- Step 9: Aggregates ---');
136
+ let tmpStats = tmpDB.prepare(`SELECT COUNT(*) as BookCount, AVG(Price) as AvgPrice, SUM(Price) as TotalValue FROM Book`).get();
137
+ _Fable.log.info(`Books: ${tmpStats.BookCount}, Average price: $${tmpStats.AvgPrice.toFixed(2)}, Total value: $${tmpStats.TotalValue.toFixed(2)}`);
138
+
139
+ // 10. Close
140
+ _Fable.log.info('--- Step 10: Close ---');
141
+ tmpDB.close();
142
+ _Fable.log.info('Database closed. Pipeline test complete!');
143
+ });
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # Meadow Connection SQLite
2
+
3
+ A Fable service provider that connects applications to SQLite databases. Wraps [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) and integrates with the Meadow data layer through Fable's dependency injection system.
4
+
5
+ SQLite databases are single files that require no server process. This makes them ideal for local development, embedded applications, desktop tools, CLI utilities, test suites, and any scenario where a full MySQL or MSSQL server is unnecessary overhead.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install meadow-connection-sqlite
11
+ ```
12
+
13
+ Requires Node.js. The `better-sqlite3` dependency compiles a native addon at install time — a C compiler toolchain must be available on the host.
14
+
15
+ ## Quick Start
16
+
17
+ ### 1. Configure Fable
18
+
19
+ Add an `SQLite` section to your Fable configuration with the path to the database file. The file is created automatically if it does not exist:
20
+
21
+ ```javascript
22
+ const libFable = require('fable');
23
+
24
+ let _Fable = new libFable(
25
+ {
26
+ "Product": "MyApp",
27
+ "SQLite":
28
+ {
29
+ "SQLiteFilePath": "./data/myapp.db"
30
+ }
31
+ });
32
+ ```
33
+
34
+ ### 2. Register the Service
35
+
36
+ ```javascript
37
+ const libMeadowConnectionSQLite = require('meadow-connection-sqlite');
38
+
39
+ _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
40
+ _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
41
+ ```
42
+
43
+ After instantiation the provider is available at `_Fable.MeadowSQLiteProvider`.
44
+
45
+ ### 3. Connect
46
+
47
+ ```javascript
48
+ _Fable.MeadowSQLiteProvider.connectAsync(
49
+ (pError, pDatabase) =>
50
+ {
51
+ if (pError)
52
+ {
53
+ _Fable.log.error(`Connection failed: ${pError}`);
54
+ return;
55
+ }
56
+
57
+ // Connection is ready — WAL journaling is enabled automatically
58
+ _Fable.log.info('SQLite connected!');
59
+ });
60
+ ```
61
+
62
+ ### 4. Query
63
+
64
+ Access the better-sqlite3 `Database` instance through the `db` getter:
65
+
66
+ ```javascript
67
+ let tmpDB = _Fable.MeadowSQLiteProvider.db;
68
+
69
+ // Create a table
70
+ tmpDB.exec(`
71
+ CREATE TABLE IF NOT EXISTS Book (
72
+ IDBook INTEGER PRIMARY KEY AUTOINCREMENT,
73
+ Title TEXT DEFAULT '',
74
+ Author TEXT DEFAULT ''
75
+ )
76
+ `);
77
+
78
+ // Insert a row
79
+ let tmpResult = tmpDB.prepare('INSERT INTO Book (Title, Author) VALUES (?, ?)').run('Dune', 'Frank Herbert');
80
+ console.log(`Inserted IDBook = ${tmpResult.lastInsertRowid}`);
81
+
82
+ // Query rows
83
+ let tmpBooks = tmpDB.prepare('SELECT * FROM Book').all();
84
+ console.log(tmpBooks);
85
+ ```
86
+
87
+ ## Configuration
88
+
89
+ The provider reads `SQLiteFilePath` from two sources, in order of priority:
90
+
91
+ 1. **Constructor options** — passed as the second argument to `instantiateServiceProvider()`
92
+ 2. **Fable settings** — `fable.settings.SQLite.SQLiteFilePath`
93
+
94
+ | Setting | Type | Description |
95
+ |---------|------|-------------|
96
+ | `SQLiteFilePath` | string | Path to the database file. Use `:memory:` for an ephemeral in-memory database. |
97
+
98
+ Any additional properties in the options object are passed through to the `better-sqlite3` constructor (e.g. `readonly`, `fileMustExist`, `timeout`).
99
+
100
+ ### In-Memory Databases
101
+
102
+ Pass `:memory:` as the file path for a database that exists only in RAM. This is useful for fast test suites:
103
+
104
+ ```javascript
105
+ let _Fable = new libFable(
106
+ {
107
+ "Product": "TestSuite",
108
+ "SQLite": { "SQLiteFilePath": ":memory:" }
109
+ });
110
+ ```
111
+
112
+ ## How It Works
113
+
114
+ ```
115
+ ┌─────────────────────────────┐
116
+ │ Fable Application │
117
+ │ │
118
+ │ fable.settings.SQLite │
119
+ │ └── SQLiteFilePath │
120
+ └───────────┬─────────────────┘
121
+ │ connectAsync()
122
+
123
+ ┌─────────────────────────────┐
124
+ │ MeadowConnectionSQLite │
125
+ │ (Fable Service Provider) │
126
+ │ │
127
+ │ .connected │
128
+ │ .db ──────────────────┐ │
129
+ │ .SQLite │ │
130
+ └────────────────────────┼────┘
131
+
132
+ ┌────────────▼────────────┐
133
+ │ better-sqlite3 │
134
+ │ │
135
+ │ .prepare(sql).run() │
136
+ │ .prepare(sql).get() │
137
+ │ .prepare(sql).all() │
138
+ │ .exec(sql) │
139
+ │ .transaction(fn) │
140
+ │ .pragma(str) │
141
+ └─────────────────────────┘
142
+ ```
143
+
144
+ The provider manages the connection lifecycle and exposes the raw `better-sqlite3` `Database` object. All queries go through better-sqlite3's synchronous API — there are no promises or callbacks for individual statements.
145
+
146
+ ## Companion Modules
147
+
148
+ | Module | Purpose |
149
+ |--------|---------|
150
+ | [Meadow](/meadow/meadow/) | ORM and data access layer |
151
+ | [FoxHound](/meadow/foxhound/) | Query DSL and SQL generation |
152
+ | [meadow-connection-mysql](/meadow/meadow-connection-mysql/) | MySQL connection provider |
153
+ | [meadow-connection-mssql](/meadow/meadow-connection-mssql/) | MSSQL connection provider |
@@ -0,0 +1,20 @@
1
+ - Getting Started
2
+
3
+ - [Overview](README.md)
4
+
5
+ - Reference
6
+
7
+ - [API Reference](api.md)
8
+
9
+ - Examples
10
+
11
+ - [Full Pipeline](examples-pipeline.md)
12
+
13
+ - Retold Ecosystem
14
+
15
+ - [Meadow](/meadow/meadow/)
16
+ - [FoxHound](/meadow/foxhound/)
17
+ - [MySQL Connector](/meadow/meadow-connection-mysql/)
18
+ - [MSSQL Connector](/meadow/meadow-connection-mssql/)
19
+ - [Fable](/fable/fable/)
20
+ - [Indoctrinate](/utility/indoctrinate/)
@@ -0,0 +1,5 @@
1
+ # Meadow Connection SQLite
2
+
3
+ - [Overview](README.md)
4
+ - [API Reference](api.md)
5
+ - [GitHub](https://github.com/stevenvelozo/meadow-connection-sqlite)