meadow 2.0.18 → 2.0.21

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.
@@ -0,0 +1,50 @@
1
+ # Contributing to Retold
2
+
3
+ We welcome contributions to Retold and its modules. This guide covers the expectations and process for contributing.
4
+
5
+ ## Code of Conduct
6
+
7
+ The Retold community values **empathy**, **equity**, **kindness**, and **thoughtfulness**. We expect all participants to treat each other with respect, assume good intent, and engage constructively. These values apply to all interactions: pull requests, issues, discussions, and code review.
8
+
9
+ ## How to Contribute
10
+
11
+ ### Pull Requests
12
+
13
+ Pull requests are the preferred method for contributing changes. To submit one:
14
+
15
+ 1. Fork the module repository you want to change
16
+ 2. Create a branch for your work
17
+ 3. Make your changes, following the code style of the module you are editing
18
+ 4. Ensure your changes have test coverage (see below)
19
+ 5. Open a pull request against the module's main branch
20
+
21
+ **Submitting a pull request does not guarantee it will be accepted.** Maintainers review contributions for fit, quality, and alignment with the project's direction. A PR may be declined, or you may be asked to revise it. This is normal and not a reflection on the quality of your effort.
22
+
23
+ ### Reporting Issues
24
+
25
+ If you find a bug or have a feature suggestion, open an issue on the relevant module's repository. Include enough detail to reproduce the problem or understand the proposal.
26
+
27
+ ## Test Coverage
28
+
29
+ Every commit must include test coverage for the changes it introduces. Retold modules use Mocha in TDD style. Before submitting:
30
+
31
+ - **Write tests** for any new functionality or bug fixes
32
+ - **Run the existing test suite** with `npm test` and confirm all tests pass
33
+ - **Check coverage** with `npm run coverage` if the module supports it
34
+
35
+ Pull requests that break existing tests or lack coverage for new code will not be merged.
36
+
37
+ ## Code Style
38
+
39
+ Follow the conventions of the module you are working in. The general Retold style is:
40
+
41
+ - **Tabs** for indentation, never spaces
42
+ - **Plain JavaScript** only (no TypeScript)
43
+ - **Allman-style braces** (opening brace on its own line)
44
+ - **Variable naming:** `pVariable` for parameters, `tmpVariable` for temporaries, `libSomething` for imports
45
+
46
+ When in doubt, match what the surrounding code does.
47
+
48
+ ## Repository Structure
49
+
50
+ Each module is its own git repository. The [retold](https://github.com/stevenvelozo/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
package/README.md CHANGED
@@ -207,9 +207,13 @@ npx docsify-cli serve docs
207
207
 
208
208
  - [foxhound](https://github.com/stevenvelozo/foxhound) - Query DSL for SQL generation
209
209
  - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition language
210
- - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Automatic REST endpoint generation
211
- - [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) - MySQL connection provider
212
- - [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) - MSSQL connection provider
213
- - [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) - SQLite connection provider
214
- - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
215
- - [orator](https://github.com/stevenvelozo/orator) - API server abstraction
210
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Auto-generated REST endpoints
211
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework
212
+
213
+ ## License
214
+
215
+ MIT
216
+
217
+ ## Contributing
218
+
219
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
@@ -0,0 +1,39 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
+ <meta name="description" content="Documentation powered by pict-docuserve">
8
+
9
+ <title>Documentation</title>
10
+
11
+ <!-- Application Stylesheet -->
12
+ <link href="https://cdn.jsdelivr.net/npm/pict-docuserve@0/dist/css/docuserve.css" rel="stylesheet">
13
+ <!-- KaTeX stylesheet for LaTeX equation rendering -->
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css">
15
+ <!-- PICT Dynamic View CSS Container -->
16
+ <style id="PICT-CSS"></style>
17
+
18
+ <!-- Load the PICT library from jsDelivr CDN -->
19
+ <script src="https://cdn.jsdelivr.net/npm/pict@1/dist/pict.min.js" type="text/javascript"></script>
20
+ <!-- Bootstrap the Application -->
21
+ <script type="text/javascript">
22
+ //<![CDATA[
23
+ Pict.safeOnDocumentReady(() => { Pict.safeLoadPictApplication(PictDocuserve, 2)});
24
+ //]]>
25
+ </script>
26
+ </head>
27
+ <body>
28
+ <!-- The root container for the Pict application -->
29
+ <div id="Docuserve-Application-Container"></div>
30
+
31
+ <!-- Mermaid diagram rendering -->
32
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
33
+ <script>mermaid.initialize({ startOnLoad: false, theme: 'default' });</script>
34
+ <!-- KaTeX for LaTeX equation rendering -->
35
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script>
36
+ <!-- Load the Docuserve PICT Application Bundle from jsDelivr CDN -->
37
+ <script src="https://cdn.jsdelivr.net/npm/pict-docuserve@0/dist/pict-docuserve.min.js" type="text/javascript"></script>
38
+ </body>
39
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meadow",
3
- "version": "2.0.18",
3
+ "version": "2.0.21",
4
4
  "description": "A data access library.",
5
5
  "main": "source/Meadow.js",
6
6
  "scripts": {
@@ -22,7 +22,8 @@
22
22
  "docker-mssql-status": "./scripts/mssql-test-db.sh status",
23
23
  "test-mssql": "./scripts/mssql-test-db.sh start && ./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep Meadow-Provider-MSSQL",
24
24
  "test-mssql-all": "./scripts/mssql-test-db.sh start && ./node_modules/mocha/bin/_mocha -u tdd --exit -R spec",
25
- "test-all-providers": "./scripts/mysql-test-db.sh start && ./scripts/mssql-test-db.sh start && ./node_modules/mocha/bin/_mocha -u tdd --exit -R spec"
25
+ "test-all-providers": "./scripts/mysql-test-db.sh start && ./scripts/mssql-test-db.sh start && ./node_modules/mocha/bin/_mocha -u tdd --exit -R spec",
26
+ "docker-cleanup": "./scripts/meadow-test-cleanup.sh"
26
27
  },
27
28
  "mocha": {
28
29
  "diff": true,
@@ -61,14 +62,14 @@
61
62
  "better-sqlite3": "^12.6.2",
62
63
  "browserify": "^17.0.0",
63
64
  "chai": "4.3.10",
64
- "fable": "^3.1.51",
65
+ "fable": "^3.1.53",
65
66
  "gulp": "^4.0.2",
66
67
  "gulp-babel": "^8.0.0",
67
68
  "gulp-sourcemaps": "^3.0.0",
68
69
  "gulp-terser": "^2.1.0",
69
70
  "gulp-util": "^3.0.8",
70
- "meadow-connection-mssql": "^1.0.9",
71
- "meadow-connection-mysql": "^1.0.4",
71
+ "meadow-connection-mssql": "^1.0.10",
72
+ "meadow-connection-mysql": "^1.0.7",
72
73
  "meadow-connection-sqlite": "file:../meadow-connection-sqlite",
73
74
  "mocha": "10.2.0",
74
75
  "mysql2": "^3.6.3",
@@ -78,7 +79,7 @@
78
79
  },
79
80
  "dependencies": {
80
81
  "async": "3.2.5",
81
- "foxhound": "^2.0.13",
82
+ "foxhound": "^2.0.16",
82
83
  "is-my-json-valid": "2.20.6",
83
84
  "npm-check-updates": "^16.14.6",
84
85
  "simple-get": "^4.0.1"
@@ -0,0 +1,147 @@
1
+ -- Bookstore Schema and Seed Data for Meadow Tests
2
+ -- Generated from meadow-connection-mysql/retold-harness/model/sql_create/BookStore-CreateDatabase.mysql.sql
3
+ -- and the first 20 rows of meadow-connection-mysql/retold-harness/data/books.csv
4
+
5
+ -- Schema
6
+
7
+ CREATE TABLE IF NOT EXISTS
8
+ Book
9
+ (
10
+ IDBook INT UNSIGNED NOT NULL AUTO_INCREMENT,
11
+ GUIDBook CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
12
+ CreateDate DATETIME,
13
+ CreatingIDUser INT NOT NULL DEFAULT '0',
14
+ UpdateDate DATETIME,
15
+ UpdatingIDUser INT NOT NULL DEFAULT '0',
16
+ Deleted TINYINT NOT NULL DEFAULT '0',
17
+ DeleteDate DATETIME,
18
+ DeletingIDUser INT NOT NULL DEFAULT '0',
19
+ Title CHAR(200) NOT NULL DEFAULT '',
20
+ Type CHAR(32) NOT NULL DEFAULT '',
21
+ Genre CHAR(128) NOT NULL DEFAULT '',
22
+ ISBN CHAR(64) NOT NULL DEFAULT '',
23
+ Language CHAR(12) NOT NULL DEFAULT '',
24
+ ImageURL CHAR(254) NOT NULL DEFAULT '',
25
+ PublicationYear INT NOT NULL DEFAULT '0',
26
+
27
+ PRIMARY KEY (IDBook)
28
+ ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
29
+
30
+ CREATE TABLE IF NOT EXISTS
31
+ BookAuthorJoin
32
+ (
33
+ IDBookAuthorJoin INT UNSIGNED NOT NULL AUTO_INCREMENT,
34
+ GUIDBookAuthorJoin CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
35
+ IDBook INT NOT NULL DEFAULT '0',
36
+ IDAuthor INT NOT NULL DEFAULT '0',
37
+
38
+ PRIMARY KEY (IDBookAuthorJoin)
39
+ ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
40
+
41
+ CREATE TABLE IF NOT EXISTS
42
+ Author
43
+ (
44
+ IDAuthor INT UNSIGNED NOT NULL AUTO_INCREMENT,
45
+ GUIDAuthor CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
46
+ CreateDate DATETIME,
47
+ CreatingIDUser INT NOT NULL DEFAULT '0',
48
+ UpdateDate DATETIME,
49
+ UpdatingIDUser INT NOT NULL DEFAULT '0',
50
+ Deleted TINYINT NOT NULL DEFAULT '0',
51
+ DeleteDate DATETIME,
52
+ DeletingIDUser INT NOT NULL DEFAULT '0',
53
+ Name CHAR(200) NOT NULL DEFAULT '',
54
+
55
+ PRIMARY KEY (IDAuthor)
56
+ ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
57
+
58
+ CREATE TABLE IF NOT EXISTS
59
+ BookPrice
60
+ (
61
+ IDBookPrice INT UNSIGNED NOT NULL AUTO_INCREMENT,
62
+ GUIDBookPrice CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
63
+ CreateDate DATETIME,
64
+ CreatingIDUser INT NOT NULL DEFAULT '0',
65
+ UpdateDate DATETIME,
66
+ UpdatingIDUser INT NOT NULL DEFAULT '0',
67
+ Deleted TINYINT NOT NULL DEFAULT '0',
68
+ DeleteDate DATETIME,
69
+ DeletingIDUser INT NOT NULL DEFAULT '0',
70
+ Price DECIMAL(8,2),
71
+ StartDate DATETIME,
72
+ EndDate DATETIME,
73
+ Discountable TINYINT NOT NULL DEFAULT '0',
74
+ CouponCode CHAR(16) NOT NULL DEFAULT '',
75
+ IDBook INT NOT NULL DEFAULT '0',
76
+
77
+ PRIMARY KEY (IDBookPrice)
78
+ ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
79
+
80
+ CREATE TABLE IF NOT EXISTS
81
+ Review
82
+ (
83
+ IDReviews INT UNSIGNED NOT NULL AUTO_INCREMENT,
84
+ GUIDReviews CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
85
+ CreateDate DATETIME,
86
+ CreatingIDUser INT NOT NULL DEFAULT '0',
87
+ UpdateDate DATETIME,
88
+ UpdatingIDUser INT NOT NULL DEFAULT '0',
89
+ Deleted TINYINT NOT NULL DEFAULT '0',
90
+ DeleteDate DATETIME,
91
+ DeletingIDUser INT NOT NULL DEFAULT '0',
92
+ Text TEXT,
93
+ Rating INT NOT NULL DEFAULT '0',
94
+ IDBook INT NOT NULL DEFAULT '0',
95
+
96
+ PRIMARY KEY (IDReviews)
97
+ ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
98
+
99
+ -- Seed Data: First 20 books from books.csv
100
+ -- Inserted in CSV order so IDBook matches CSV row number
101
+
102
+ INSERT INTO Book (Title, Type, Genre, ISBN, Language, ImageURL, PublicationYear, CreateDate, CreatingIDUser, UpdateDate, UpdatingIDUser) VALUES
103
+ ('The Hunger Games', 'Paper', 'UNKNOWN', '439023483', 'eng', 'https://images.gr-assets.com/books/1447303603m/2767052.jpg', 2008, NOW(), 99999, NOW(), 99999),
104
+ ('Harry Potter and the Philosopher''s Stone', 'Paper', 'UNKNOWN', '439554934', 'eng', 'https://images.gr-assets.com/books/1474154022m/3.jpg', 1997, NOW(), 99999, NOW(), 99999),
105
+ ('Twilight', 'Paper', 'UNKNOWN', '316015849', 'en-US', 'https://images.gr-assets.com/books/1361039443m/41865.jpg', 2005, NOW(), 99999, NOW(), 99999),
106
+ ('To Kill a Mockingbird', 'Paper', 'UNKNOWN', '61120081', 'eng', 'https://images.gr-assets.com/books/1361975680m/2657.jpg', 1960, NOW(), 99999, NOW(), 99999),
107
+ ('The Great Gatsby', 'Paper', 'UNKNOWN', '743273567', 'eng', 'https://images.gr-assets.com/books/1490528560m/4671.jpg', 1925, NOW(), 99999, NOW(), 99999),
108
+ ('The Fault in Our Stars', 'Paper', 'UNKNOWN', '525478817', 'eng', 'https://images.gr-assets.com/books/1360206420m/11870085.jpg', 2012, NOW(), 99999, NOW(), 99999),
109
+ ('The Hobbit or There and Back Again', 'Paper', 'UNKNOWN', '618260307', 'en-US', 'https://images.gr-assets.com/books/1372847500m/5907.jpg', 1937, NOW(), 99999, NOW(), 99999),
110
+ ('The Catcher in the Rye', 'Paper', 'UNKNOWN', '316769177', 'eng', 'https://images.gr-assets.com/books/1398034300m/5107.jpg', 1951, NOW(), 99999, NOW(), 99999),
111
+ ('Angels & Demons', 'Paper', 'UNKNOWN', '1416524797', 'en-CA', 'https://images.gr-assets.com/books/1303390735m/960.jpg', 2000, NOW(), 99999, NOW(), 99999),
112
+ ('Pride and Prejudice', 'Paper', 'UNKNOWN', '679783261', 'eng', 'https://images.gr-assets.com/books/1320399351m/1885.jpg', 1813, NOW(), 99999, NOW(), 99999),
113
+ ('The Kite Runner', 'Paper', 'UNKNOWN', '1594480001', 'eng', 'https://images.gr-assets.com/books/1484565687m/77203.jpg', 2003, NOW(), 99999, NOW(), 99999),
114
+ ('Divergent', 'Paper', 'UNKNOWN', '62024035', 'eng', 'https://images.gr-assets.com/books/1328559506m/13335037.jpg', 2011, NOW(), 99999, NOW(), 99999),
115
+ ('Nineteen Eighty-Four', 'Paper', 'UNKNOWN', '451524934', 'eng', 'https://images.gr-assets.com/books/1348990566m/5470.jpg', 1949, NOW(), 99999, NOW(), 99999),
116
+ ('Animal Farm: A Fairy Story', 'Paper', 'UNKNOWN', '452284244', 'eng', 'https://images.gr-assets.com/books/1424037542m/7613.jpg', 1945, NOW(), 99999, NOW(), 99999),
117
+ ('Het Achterhuis: Dagboekbrieven 14 juni 1942 - 1 augustus 1944', 'Paper', 'UNKNOWN', '553296981', 'eng', 'https://images.gr-assets.com/books/1358276407m/48855.jpg', 1947, NOW(), 99999, NOW(), 99999),
118
+ ('Män som hatar kvinnor', 'Paper', 'UNKNOWN', '307269752', 'eng', 'https://images.gr-assets.com/books/1327868566m/2429135.jpg', 2005, NOW(), 99999, NOW(), 99999),
119
+ ('Catching Fire', 'Paper', 'UNKNOWN', '439023491', 'eng', 'https://images.gr-assets.com/books/1358273780m/6148028.jpg', 2009, NOW(), 99999, NOW(), 99999),
120
+ ('Harry Potter and the Prisoner of Azkaban', 'Paper', 'UNKNOWN', '043965548X', 'eng', 'https://images.gr-assets.com/books/1499277281m/5.jpg', 1999, NOW(), 99999, NOW(), 99999),
121
+ ('The Fellowship of the Ring', 'Paper', 'UNKNOWN', '618346252', 'eng', 'https://images.gr-assets.com/books/1298411339m/34.jpg', 1954, NOW(), 99999, NOW(), 99999),
122
+ ('Mockingjay', 'Paper', 'UNKNOWN', '439023513', 'eng', 'https://images.gr-assets.com/books/1358275419m/7260188.jpg', 2010, NOW(), 99999, NOW(), 99999);
123
+
124
+ -- Seed Data: Authors for the first 20 books
125
+
126
+ INSERT INTO Author (Name, CreateDate, CreatingIDUser, UpdateDate, UpdatingIDUser) VALUES
127
+ ('Suzanne Collins', NOW(), 99999, NOW(), 99999),
128
+ ('J.K. Rowling', NOW(), 99999, NOW(), 99999),
129
+ ('Mary GrandPré', NOW(), 99999, NOW(), 99999),
130
+ ('Stephenie Meyer', NOW(), 99999, NOW(), 99999),
131
+ ('Harper Lee', NOW(), 99999, NOW(), 99999),
132
+ ('F. Scott Fitzgerald', NOW(), 99999, NOW(), 99999),
133
+ ('John Green', NOW(), 99999, NOW(), 99999),
134
+ ('J.R.R. Tolkien', NOW(), 99999, NOW(), 99999),
135
+ ('J.D. Salinger', NOW(), 99999, NOW(), 99999),
136
+ ('Dan Brown', NOW(), 99999, NOW(), 99999),
137
+ ('Jane Austen', NOW(), 99999, NOW(), 99999),
138
+ ('Khaled Hosseini', NOW(), 99999, NOW(), 99999),
139
+ ('Veronica Roth', NOW(), 99999, NOW(), 99999),
140
+ ('George Orwell', NOW(), 99999, NOW(), 99999),
141
+ ('Erich Fromm', NOW(), 99999, NOW(), 99999),
142
+ ('Anne Frank', NOW(), 99999, NOW(), 99999),
143
+ ('Eleanor Roosevelt', NOW(), 99999, NOW(), 99999),
144
+ ('B.M. Mooyaart-Doubleday', NOW(), 99999, NOW(), 99999),
145
+ ('Stieg Larsson', NOW(), 99999, NOW(), 99999),
146
+ ('Reg Keeland', NOW(), 99999, NOW(), 99999),
147
+ ('Rufus Beck', NOW(), 99999, NOW(), 99999);
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+ # Meadow Test Database Cleanup Script
3
+ #
4
+ # Stops and removes both MySQL and MSSQL test containers.
5
+ #
6
+ # Usage:
7
+ # ./scripts/meadow-test-cleanup.sh
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+
11
+ echo "Cleaning up meadow test database containers..."
12
+ echo ""
13
+
14
+ "${SCRIPT_DIR}/mysql-test-db.sh" stop
15
+ "${SCRIPT_DIR}/mssql-test-db.sh" stop
16
+
17
+ echo ""
18
+ echo "Cleanup complete."
@@ -8,13 +8,13 @@
8
8
  #
9
9
  # The container settings match the test configuration in
10
10
  # test/Meadow-Provider-MSSQL_tests.js:
11
- # Host: 127.0.0.1, Port: 14333, User: sa
11
+ # Host: 127.0.0.1, Port: 31433, User: sa
12
12
  # Password: 1234567890abc., Database: bookstore
13
13
 
14
14
  CONTAINER_NAME="meadow-mssql-test"
15
15
  SA_PASSWORD="1234567890abc."
16
16
  MSSQL_DATABASE="bookstore"
17
- MSSQL_PORT="14333"
17
+ MSSQL_PORT="31433"
18
18
  MSSQL_IMAGE="mcr.microsoft.com/mssql/server:2022-latest"
19
19
 
20
20
  start_mssql() {
@@ -2,21 +2,24 @@
2
2
  # MySQL Test Database Management Script
3
3
  #
4
4
  # Usage:
5
- # ./scripts/mysql-test-db.sh start - Start MySQL container and wait for readiness
5
+ # ./scripts/mysql-test-db.sh start - Start MySQL container, load schema and seed data
6
6
  # ./scripts/mysql-test-db.sh stop - Stop and remove the container
7
7
  # ./scripts/mysql-test-db.sh status - Check if the container is running
8
8
  #
9
9
  # The container settings match the test configuration in
10
- # test/Meadow-Provider-MySQL_tests.js:
11
- # Host: localhost, Port: 3306, User: root
10
+ # test/Meadow-Provider-MySQL_tests.js and meadow-connection-mysql:
11
+ # Host: localhost, Port: 33306, User: root
12
12
  # Password: 123456789, Database: bookstore
13
13
 
14
14
  CONTAINER_NAME="meadow-mysql-test"
15
15
  MYSQL_ROOT_PASSWORD="123456789"
16
16
  MYSQL_DATABASE="bookstore"
17
- MYSQL_PORT="3306"
17
+ MYSQL_PORT="33306"
18
18
  MYSQL_IMAGE="mysql:8.0"
19
19
 
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ SEED_SQL="${SCRIPT_DIR}/bookstore-seed.sql"
22
+
20
23
  start_mysql() {
21
24
  # Check if container already exists
22
25
  if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
@@ -58,6 +61,20 @@ start_mysql() {
58
61
  sleep 2
59
62
  done
60
63
 
64
+ # Load bookstore schema and seed data
65
+ if [ -f "${SEED_SQL}" ]; then
66
+ echo "Loading bookstore schema and seed data..."
67
+ docker cp "${SEED_SQL}" "${CONTAINER_NAME}:/tmp/bookstore-seed.sql"
68
+ docker exec "${CONTAINER_NAME}" mysql -u root -p"${MYSQL_ROOT_PASSWORD}" "${MYSQL_DATABASE}" -e "source /tmp/bookstore-seed.sql"
69
+ if [ $? -ne 0 ]; then
70
+ echo "WARNING: Failed to load seed data. Tests requiring pre-populated data may fail."
71
+ else
72
+ echo "Bookstore schema and seed data loaded successfully."
73
+ fi
74
+ else
75
+ echo "WARNING: Seed file not found at ${SEED_SQL}. Skipping schema/data loading."
76
+ fi
77
+
61
78
  echo ""
62
79
  echo "MySQL test database is ready!"
63
80
  echo " Container: ${CONTAINER_NAME}"
@@ -66,6 +66,35 @@ var MeadowProvider = function ()
66
66
  * which better-sqlite3 supports natively.
67
67
  */
68
68
 
69
+ /**
70
+ * Coerce query parameter values so they are safe for better-sqlite3.
71
+ *
72
+ * better-sqlite3 only accepts numbers, strings, bigints, buffers and null.
73
+ * Booleans (e.g. Deleted: false) must be converted to integers.
74
+ * Undefined values must be converted to null.
75
+ */
76
+ var coerceParameters = function (pParams)
77
+ {
78
+ if (typeof (pParams) !== 'object' || pParams === null)
79
+ {
80
+ return pParams;
81
+ }
82
+ var tmpKeys = Object.keys(pParams);
83
+ for (var i = 0; i < tmpKeys.length; i++)
84
+ {
85
+ var tmpValue = pParams[tmpKeys[i]];
86
+ if (typeof (tmpValue) === 'boolean')
87
+ {
88
+ pParams[tmpKeys[i]] = tmpValue ? 1 : 0;
89
+ }
90
+ else if (typeof (tmpValue) === 'undefined')
91
+ {
92
+ pParams[tmpKeys[i]] = null;
93
+ }
94
+ }
95
+ return pParams;
96
+ };
97
+
69
98
  // The Meadow marshaller also passes in the Schema as the third parameter, but this is a blunt function ATM.
70
99
  var marshalRecordFromSourceToObject = function (pObject, pRecord)
71
100
  {
@@ -83,6 +112,7 @@ var MeadowProvider = function ()
83
112
  pQuery.setDialect('SQLite').buildCreateQuery();
84
113
 
85
114
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
115
+ coerceParameters(pQuery.query.parameters);
86
116
 
87
117
  if (pQuery.logLevel > 0)
88
118
  {
@@ -132,6 +162,7 @@ var MeadowProvider = function ()
132
162
  pQuery.setDialect('SQLite').buildReadQuery();
133
163
 
134
164
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
165
+ coerceParameters(pQuery.query.parameters);
135
166
 
136
167
  if (pQuery.logLevel > 0)
137
168
  {
@@ -172,6 +203,7 @@ var MeadowProvider = function ()
172
203
  pQuery.setDialect('SQLite').buildUpdateQuery();
173
204
 
174
205
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
206
+ coerceParameters(pQuery.query.parameters);
175
207
 
176
208
  if (pQuery.logLevel > 0)
177
209
  {
@@ -212,6 +244,7 @@ var MeadowProvider = function ()
212
244
  pQuery.setDialect('SQLite').buildDeleteQuery();
213
245
 
214
246
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
247
+ coerceParameters(pQuery.query.parameters);
215
248
 
216
249
  if (pQuery.logLevel > 0)
217
250
  {
@@ -260,6 +293,7 @@ var MeadowProvider = function ()
260
293
  pQuery.setDialect('SQLite').buildUndeleteQuery();
261
294
 
262
295
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
296
+ coerceParameters(pQuery.query.parameters);
263
297
 
264
298
  if (pQuery.logLevel > 0)
265
299
  {
@@ -308,6 +342,7 @@ var MeadowProvider = function ()
308
342
  pQuery.setDialect('SQLite').buildCountQuery();
309
343
 
310
344
  var tmpQueryBody = fixDateFunctions(pQuery.query.body);
345
+ coerceParameters(pQuery.query.parameters);
311
346
 
312
347
  if (pQuery.logLevel > 0)
313
348
  {
@@ -33,7 +33,7 @@ var tmpFableSettings = (
33
33
  "MSSQL":
34
34
  {
35
35
  "server": "127.0.0.1",
36
- "port": 14333,
36
+ "port": 31433,
37
37
  "user": "sa",
38
38
  "password": "1234567890abc.",
39
39
  "database": "bookstore",
@@ -21,7 +21,7 @@ var tmpFableSettings = (
21
21
  {
22
22
  // This is queued up for Travis defaults.
23
23
  Server: "localhost",
24
- Port: 3306,
24
+ Port: 33306,
25
25
  User: "root",
26
26
  Password: "123456789",
27
27
  Database: "bookstore",
@@ -268,7 +268,7 @@ suite
268
268
  {
269
269
  // This is queued up for Travis defaults.
270
270
  Server: "localhost",
271
- Port: 3306,
271
+ Port: 33306,
272
272
  User: "root",
273
273
  Password: "123456789",
274
274
  Database: "bookstore",