meadow-connection-mssql 1.0.10 → 1.0.12
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/CONTRIBUTING.md +50 -0
- package/README.md +8 -3
- package/docker-compose.yml +12 -0
- package/docs/retold-catalog.json +37 -1
- package/package.json +10 -6
- package/start-mssql.sh +25 -0
- package/stop-mssql.sh +9 -0
- package/test/MSSQL_tests.js +4 -4
- package/test/docker-init/01-schema.sql +135 -0
- package/test/docker-init/init-db.js +127 -0
- /package/docs/{cover.md → _cover.md} +0 -0
package/CONTRIBUTING.md
ADDED
|
@@ -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
|
@@ -193,10 +193,15 @@ Run with coverage:
|
|
|
193
193
|
npm run coverage
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
+
## Related Packages
|
|
197
|
+
|
|
198
|
+
- [meadow](https://github.com/stevenvelozo/meadow) - Data access and ORM
|
|
199
|
+
- [fable](https://github.com/stevenvelozo/fable) - Application services framework
|
|
200
|
+
|
|
196
201
|
## License
|
|
197
202
|
|
|
198
|
-
MIT
|
|
203
|
+
MIT
|
|
199
204
|
|
|
200
|
-
##
|
|
205
|
+
## Contributing
|
|
201
206
|
|
|
202
|
-
|
|
207
|
+
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,12 @@
|
|
|
1
|
+
services:
|
|
2
|
+
mssql-test:
|
|
3
|
+
image: mcr.microsoft.com/mssql/server:2022-latest
|
|
4
|
+
platform: linux/amd64
|
|
5
|
+
container_name: meadow-connection-mssql-test
|
|
6
|
+
environment:
|
|
7
|
+
ACCEPT_EULA: "Y"
|
|
8
|
+
MSSQL_SA_PASSWORD: "Retold1234567890!"
|
|
9
|
+
ports:
|
|
10
|
+
- "21433:1433"
|
|
11
|
+
volumes:
|
|
12
|
+
- ./test/docker-init:/docker-init
|
package/docs/retold-catalog.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"Generated": "2026-02-
|
|
2
|
+
"Generated": "2026-02-18T03:44:10.088Z",
|
|
3
3
|
"GitHubOrg": "stevenvelozo",
|
|
4
4
|
"DefaultBranch": "master",
|
|
5
5
|
"Groups": [
|
|
@@ -37,6 +37,25 @@
|
|
|
37
37
|
}
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
"Name": "Docs",
|
|
42
|
+
"Key": "docs",
|
|
43
|
+
"Description": "",
|
|
44
|
+
"Modules": [
|
|
45
|
+
{
|
|
46
|
+
"Name": "css",
|
|
47
|
+
"Repo": "css",
|
|
48
|
+
"Group": "docs",
|
|
49
|
+
"Branch": "master",
|
|
50
|
+
"HasDocs": true,
|
|
51
|
+
"HasCover": false,
|
|
52
|
+
"Sidebar": [],
|
|
53
|
+
"DocFiles": [
|
|
54
|
+
"css/docuserve.css"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
40
59
|
{
|
|
41
60
|
"Name": "Retold-harness",
|
|
42
61
|
"Key": "retold-harness",
|
|
@@ -73,6 +92,23 @@
|
|
|
73
92
|
"DocFiles": []
|
|
74
93
|
}
|
|
75
94
|
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"Name": "Test",
|
|
98
|
+
"Key": "test",
|
|
99
|
+
"Description": "",
|
|
100
|
+
"Modules": [
|
|
101
|
+
{
|
|
102
|
+
"Name": "docker-init",
|
|
103
|
+
"Repo": "docker-init",
|
|
104
|
+
"Group": "test",
|
|
105
|
+
"Branch": "master",
|
|
106
|
+
"HasDocs": false,
|
|
107
|
+
"HasCover": false,
|
|
108
|
+
"Sidebar": [],
|
|
109
|
+
"DocFiles": []
|
|
110
|
+
}
|
|
111
|
+
]
|
|
76
112
|
}
|
|
77
113
|
]
|
|
78
114
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meadow-connection-mssql",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Meadow MSSQL Plugin",
|
|
5
5
|
"main": "source/Meadow-Connection-MSSQL.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"coverage": "
|
|
8
|
-
"test": "
|
|
7
|
+
"coverage": "npx quack coverage",
|
|
8
|
+
"test": "npx quack test",
|
|
9
|
+
"docker-mssql-start": "bash ./start-mssql.sh",
|
|
10
|
+
"docker-mssql-stop": "bash ./stop-mssql.sh",
|
|
11
|
+
"test-docker": "bash ./start-mssql.sh && npm test; bash ./stop-mssql.sh",
|
|
9
12
|
"docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t retold/meadow-connection-mssql:local",
|
|
10
13
|
"docker-dev-run": "docker run -it -d --name retold-meadow-connection-mssql-dev -p 38001:8080 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/meadow-connection-mssql\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/meadow-connection-mssql:local",
|
|
11
14
|
"docker-dev-shell": "docker exec -it retold-meadow-connection-mssql-dev /bin/bash",
|
|
12
15
|
"start": "node source/Meadow-Connection-MSSQL.js",
|
|
13
|
-
"tests": "npx
|
|
16
|
+
"tests": "npx quack test -g",
|
|
14
17
|
"build": "npx quack build"
|
|
15
18
|
},
|
|
16
19
|
"mocha": {
|
|
@@ -45,10 +48,11 @@
|
|
|
45
48
|
},
|
|
46
49
|
"homepage": "https://github.com/stevenvelozo/meadow-connection-mssql",
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"
|
|
51
|
+
"fable": "^3.1.55",
|
|
52
|
+
"quackage": "^1.0.58"
|
|
49
53
|
},
|
|
50
54
|
"dependencies": {
|
|
51
|
-
"fable-serviceproviderbase": "^3.0.
|
|
55
|
+
"fable-serviceproviderbase": "^3.0.19",
|
|
52
56
|
"mssql": "^9.1.1"
|
|
53
57
|
}
|
|
54
58
|
}
|
package/start-mssql.sh
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Start the MSSQL test server in Docker
|
|
3
|
+
# Uses port 21433 to avoid conflicts with any local MSSQL instance
|
|
4
|
+
# Uses linux/amd64 platform (runs under Rosetta on Apple Silicon)
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
|
|
8
|
+
echo "Starting MSSQL test server on port 21433..."
|
|
9
|
+
docker compose -f "${SCRIPT_DIR}/docker-compose.yml" up -d
|
|
10
|
+
|
|
11
|
+
echo "Initializing database (will retry until MSSQL is ready)..."
|
|
12
|
+
node "${SCRIPT_DIR}/test/docker-init/init-db.js"
|
|
13
|
+
|
|
14
|
+
if [ $? -ne 0 ]; then
|
|
15
|
+
echo "ERROR: Database initialization failed"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo "MSSQL test server is ready on port 21433"
|
|
21
|
+
echo " Host: 127.0.0.1"
|
|
22
|
+
echo " Port: 21433"
|
|
23
|
+
echo " User: sa"
|
|
24
|
+
echo " Password: Retold1234567890!"
|
|
25
|
+
echo " Database: bookstore"
|
package/stop-mssql.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Stop and remove the MSSQL test server Docker container
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
|
|
6
|
+
echo "Stopping MSSQL test server..."
|
|
7
|
+
docker compose -f "${SCRIPT_DIR}/docker-compose.yml" down -v
|
|
8
|
+
|
|
9
|
+
echo "MSSQL test server stopped and volumes removed."
|
package/test/MSSQL_tests.js
CHANGED
|
@@ -33,9 +33,9 @@ const _FableConfig = (
|
|
|
33
33
|
"MSSQL":
|
|
34
34
|
{
|
|
35
35
|
"server": "localhost",
|
|
36
|
-
"port":
|
|
36
|
+
"port": 21433,
|
|
37
37
|
"user": "sa",
|
|
38
|
-
"password": "
|
|
38
|
+
"password": "Retold1234567890!",
|
|
39
39
|
"database": "bookstore",
|
|
40
40
|
"ConnectionPoolLimit": 20
|
|
41
41
|
}
|
|
@@ -76,8 +76,8 @@ suite
|
|
|
76
76
|
(pError, pRows, pFields) =>
|
|
77
77
|
{
|
|
78
78
|
Expect(pRows.recordset).to.be.an('array');
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
Expect(pRows.recordset.length).to.equal(10);
|
|
80
|
+
Expect(pRows.recordset[0].Title).to.equal(`The Hunger Games`);
|
|
81
81
|
return fDone();
|
|
82
82
|
});
|
|
83
83
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
-- Bookstore schema and seed data for meadow-connection-mssql tests
|
|
2
|
+
|
|
3
|
+
CREATE DATABASE bookstore;
|
|
4
|
+
GO
|
|
5
|
+
|
|
6
|
+
USE bookstore;
|
|
7
|
+
GO
|
|
8
|
+
|
|
9
|
+
-- [ FableTest ] - Simple table used by the basic connection test
|
|
10
|
+
CREATE TABLE [dbo].[FableTest]
|
|
11
|
+
(
|
|
12
|
+
[IDFableTest] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
13
|
+
[Title] VARCHAR(200) DEFAULT '',
|
|
14
|
+
[Value] VARCHAR(200) DEFAULT ''
|
|
15
|
+
);
|
|
16
|
+
GO
|
|
17
|
+
|
|
18
|
+
-- [ Book ]
|
|
19
|
+
CREATE TABLE [dbo].[Book]
|
|
20
|
+
(
|
|
21
|
+
[IDBook] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
22
|
+
[GUIDBook] VARCHAR(36) DEFAULT '00000000-0000-0000-0000-000000000000',
|
|
23
|
+
[CreateDate] DATETIME,
|
|
24
|
+
[CreatingIDUser] INT NOT NULL DEFAULT 0,
|
|
25
|
+
[UpdateDate] DATETIME,
|
|
26
|
+
[UpdatingIDUser] INT NOT NULL DEFAULT 0,
|
|
27
|
+
[Deleted] TINYINT DEFAULT 0,
|
|
28
|
+
[DeleteDate] DATETIME,
|
|
29
|
+
[DeletingIDUser] INT NOT NULL DEFAULT 0,
|
|
30
|
+
[Title] VARCHAR(200) DEFAULT '',
|
|
31
|
+
[Type] VARCHAR(32) DEFAULT '',
|
|
32
|
+
[Genre] VARCHAR(128) DEFAULT '',
|
|
33
|
+
[ISBN] VARCHAR(64) DEFAULT '',
|
|
34
|
+
[Language] VARCHAR(12) DEFAULT '',
|
|
35
|
+
[ImageURL] VARCHAR(254) DEFAULT '',
|
|
36
|
+
[PublicationYear] INT NOT NULL DEFAULT 0
|
|
37
|
+
);
|
|
38
|
+
GO
|
|
39
|
+
|
|
40
|
+
-- [ BookAuthorJoin ]
|
|
41
|
+
CREATE TABLE [dbo].[BookAuthorJoin]
|
|
42
|
+
(
|
|
43
|
+
[IDBookAuthorJoin] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
44
|
+
[GUIDBookAuthorJoin] VARCHAR(36) DEFAULT '00000000-0000-0000-0000-000000000000',
|
|
45
|
+
[IDBook] INT NOT NULL DEFAULT 0,
|
|
46
|
+
[IDAuthor] INT NOT NULL DEFAULT 0
|
|
47
|
+
);
|
|
48
|
+
GO
|
|
49
|
+
|
|
50
|
+
-- [ Author ]
|
|
51
|
+
CREATE TABLE [dbo].[Author]
|
|
52
|
+
(
|
|
53
|
+
[IDAuthor] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
54
|
+
[GUIDAuthor] VARCHAR(36) DEFAULT '00000000-0000-0000-0000-000000000000',
|
|
55
|
+
[CreateDate] DATETIME,
|
|
56
|
+
[CreatingIDUser] INT NOT NULL DEFAULT 0,
|
|
57
|
+
[UpdateDate] DATETIME,
|
|
58
|
+
[UpdatingIDUser] INT NOT NULL DEFAULT 0,
|
|
59
|
+
[Deleted] TINYINT DEFAULT 0,
|
|
60
|
+
[DeleteDate] DATETIME,
|
|
61
|
+
[DeletingIDUser] INT NOT NULL DEFAULT 0,
|
|
62
|
+
[Name] VARCHAR(200) DEFAULT ''
|
|
63
|
+
);
|
|
64
|
+
GO
|
|
65
|
+
|
|
66
|
+
-- [ BookPrice ]
|
|
67
|
+
CREATE TABLE [dbo].[BookPrice]
|
|
68
|
+
(
|
|
69
|
+
[IDBookPrice] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
70
|
+
[GUIDBookPrice] VARCHAR(36) DEFAULT '00000000-0000-0000-0000-000000000000',
|
|
71
|
+
[CreateDate] DATETIME,
|
|
72
|
+
[CreatingIDUser] INT NOT NULL DEFAULT 0,
|
|
73
|
+
[UpdateDate] DATETIME,
|
|
74
|
+
[UpdatingIDUser] INT NOT NULL DEFAULT 0,
|
|
75
|
+
[Deleted] TINYINT DEFAULT 0,
|
|
76
|
+
[DeleteDate] DATETIME,
|
|
77
|
+
[DeletingIDUser] INT NOT NULL DEFAULT 0,
|
|
78
|
+
[Price] DECIMAL(8,2),
|
|
79
|
+
[StartDate] DATETIME,
|
|
80
|
+
[EndDate] DATETIME,
|
|
81
|
+
[Discountable] TINYINT DEFAULT 0,
|
|
82
|
+
[CouponCode] VARCHAR(16) DEFAULT '',
|
|
83
|
+
[IDBook] INT NOT NULL DEFAULT 0
|
|
84
|
+
);
|
|
85
|
+
GO
|
|
86
|
+
|
|
87
|
+
-- [ Review ]
|
|
88
|
+
CREATE TABLE [dbo].[Review]
|
|
89
|
+
(
|
|
90
|
+
[IDReviews] INT NOT NULL IDENTITY PRIMARY KEY,
|
|
91
|
+
[GUIDReviews] VARCHAR(36) DEFAULT '00000000-0000-0000-0000-000000000000',
|
|
92
|
+
[CreateDate] DATETIME,
|
|
93
|
+
[CreatingIDUser] INT NOT NULL DEFAULT 0,
|
|
94
|
+
[UpdateDate] DATETIME,
|
|
95
|
+
[UpdatingIDUser] INT NOT NULL DEFAULT 0,
|
|
96
|
+
[Deleted] TINYINT DEFAULT 0,
|
|
97
|
+
[DeleteDate] DATETIME,
|
|
98
|
+
[DeletingIDUser] INT NOT NULL DEFAULT 0,
|
|
99
|
+
[Text] TEXT,
|
|
100
|
+
[Rating] INT NOT NULL DEFAULT 0,
|
|
101
|
+
[IDBook] INT NOT NULL DEFAULT 0
|
|
102
|
+
);
|
|
103
|
+
GO
|
|
104
|
+
|
|
105
|
+
-- Seed data for FableTest
|
|
106
|
+
INSERT INTO FableTest (Title, Value) VALUES
|
|
107
|
+
('The Hunger Games', 'Test Value 1'),
|
|
108
|
+
('Harry Potter and the Philosopher''s Stone', 'Test Value 2'),
|
|
109
|
+
('Twilight', 'Test Value 3'),
|
|
110
|
+
('To Kill a Mockingbird', 'Test Value 4'),
|
|
111
|
+
('The Great Gatsby', 'Test Value 5'),
|
|
112
|
+
('The Fault in Our Stars', 'Test Value 6'),
|
|
113
|
+
('The Hobbit', 'Test Value 7'),
|
|
114
|
+
('The Catcher in the Rye', 'Test Value 8'),
|
|
115
|
+
('Angels & Demons', 'Test Value 9'),
|
|
116
|
+
('Pride and Prejudice', 'Test Value 10'),
|
|
117
|
+
('The Kite Runner', 'Test Value 11'),
|
|
118
|
+
('Divergent', 'Test Value 12');
|
|
119
|
+
GO
|
|
120
|
+
|
|
121
|
+
-- Seed data for Book
|
|
122
|
+
INSERT INTO Book (Title, Type, Genre, ISBN, Language, PublicationYear) VALUES
|
|
123
|
+
('The Hunger Games', 'Paper', 'UNKNOWN', '439023483', 'eng', 2008),
|
|
124
|
+
('Harry Potter and the Philosopher''s Stone', 'Paper', 'UNKNOWN', '439554934', 'eng', 1997),
|
|
125
|
+
('Twilight', 'Paper', 'UNKNOWN', '316015849', 'en-US', 2005),
|
|
126
|
+
('To Kill a Mockingbird', 'Paper', 'UNKNOWN', '61120081', 'eng', 1960),
|
|
127
|
+
('The Great Gatsby', 'Paper', 'UNKNOWN', '743273567', 'eng', 1925),
|
|
128
|
+
('The Fault in Our Stars', 'Paper', 'UNKNOWN', '525478817', 'eng', 2012),
|
|
129
|
+
('The Hobbit', 'Paper', 'UNKNOWN', '618260307', 'en-US', 1937),
|
|
130
|
+
('The Catcher in the Rye', 'Paper', 'UNKNOWN', '316769177', 'eng', 1951),
|
|
131
|
+
('Angels & Demons', 'Paper', 'UNKNOWN', '1416524797', 'en-CA', 2000),
|
|
132
|
+
('Pride and Prejudice', 'Paper', 'UNKNOWN', '679783261', 'eng', 1813),
|
|
133
|
+
('The Kite Runner', 'Paper', 'UNKNOWN', '1594480001', 'eng', 2003),
|
|
134
|
+
('Divergent', 'Paper', 'UNKNOWN', '62024035', 'eng', 2011);
|
|
135
|
+
GO
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Initialize the MSSQL test database from the host.
|
|
4
|
+
* Uses the mssql npm package to connect and run schema + seed SQL.
|
|
5
|
+
*/
|
|
6
|
+
const libMSSQL = require('mssql');
|
|
7
|
+
const libFS = require('fs');
|
|
8
|
+
const libPath = require('path');
|
|
9
|
+
|
|
10
|
+
const MSSQL_CONFIG = {
|
|
11
|
+
server: '127.0.0.1',
|
|
12
|
+
port: 21433,
|
|
13
|
+
user: 'sa',
|
|
14
|
+
password: 'Retold1234567890!',
|
|
15
|
+
requestTimeout: 30000,
|
|
16
|
+
connectionTimeout: 10000,
|
|
17
|
+
options: {
|
|
18
|
+
trustServerCertificate: true
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const MAX_CONNECT_RETRIES = 30;
|
|
23
|
+
const RETRY_DELAY_MS = 3000;
|
|
24
|
+
|
|
25
|
+
async function connectWithRetry(pConfig)
|
|
26
|
+
{
|
|
27
|
+
for (let i = 1; i <= MAX_CONNECT_RETRIES; i++)
|
|
28
|
+
{
|
|
29
|
+
try
|
|
30
|
+
{
|
|
31
|
+
let tmpPool = await libMSSQL.connect(pConfig);
|
|
32
|
+
return tmpPool;
|
|
33
|
+
}
|
|
34
|
+
catch (pError)
|
|
35
|
+
{
|
|
36
|
+
if (i >= MAX_CONNECT_RETRIES)
|
|
37
|
+
{
|
|
38
|
+
throw pError;
|
|
39
|
+
}
|
|
40
|
+
console.log(` Connection attempt ${i}/${MAX_CONNECT_RETRIES} failed, retrying in ${RETRY_DELAY_MS / 1000}s...`);
|
|
41
|
+
await new Promise((fResolve) => setTimeout(fResolve, RETRY_DELAY_MS));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function run()
|
|
47
|
+
{
|
|
48
|
+
let tmpPool;
|
|
49
|
+
try
|
|
50
|
+
{
|
|
51
|
+
// Connect to master to create the database
|
|
52
|
+
console.log('Connecting to MSSQL...');
|
|
53
|
+
tmpPool = await connectWithRetry(Object.assign({}, MSSQL_CONFIG, { database: 'master' }));
|
|
54
|
+
console.log('Connected to MSSQL.');
|
|
55
|
+
|
|
56
|
+
// Check if bookstore database already exists
|
|
57
|
+
let tmpResult = await tmpPool.query`SELECT name FROM sys.databases WHERE name = 'bookstore'`;
|
|
58
|
+
if (tmpResult.recordset.length > 0)
|
|
59
|
+
{
|
|
60
|
+
console.log('Database "bookstore" already exists, skipping initialization.');
|
|
61
|
+
await tmpPool.close();
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Read the SQL file and split on GO statements
|
|
66
|
+
let tmpSQLPath = libPath.join(__dirname, '01-schema.sql');
|
|
67
|
+
let tmpSQL = libFS.readFileSync(tmpSQLPath, 'utf8');
|
|
68
|
+
|
|
69
|
+
// Split on GO lines (MSSQL batch separator)
|
|
70
|
+
let tmpBatches = tmpSQL.split(/^\s*GO\s*$/mi).filter((pBatch) => pBatch.trim().length > 0);
|
|
71
|
+
|
|
72
|
+
console.log(`Running ${tmpBatches.length} SQL batches...`);
|
|
73
|
+
for (let i = 0; i < tmpBatches.length; i++)
|
|
74
|
+
{
|
|
75
|
+
let tmpBatch = tmpBatches[i].trim();
|
|
76
|
+
if (tmpBatch.length === 0)
|
|
77
|
+
{
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// After CREATE DATABASE, reconnect to bookstore
|
|
82
|
+
if (tmpBatch.toUpperCase().indexOf('CREATE DATABASE') >= 0)
|
|
83
|
+
{
|
|
84
|
+
await tmpPool.query(tmpBatch);
|
|
85
|
+
console.log(` Batch ${i + 1}: CREATE DATABASE bookstore`);
|
|
86
|
+
await tmpPool.close();
|
|
87
|
+
// Delay for database to be ready (especially under Rosetta emulation)
|
|
88
|
+
await new Promise((fResolve) => setTimeout(fResolve, 3000));
|
|
89
|
+
tmpPool = await connectWithRetry(Object.assign({}, MSSQL_CONFIG, { database: 'bookstore' }));
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Skip USE statements (we already connected to the right DB)
|
|
94
|
+
if (tmpBatch.toUpperCase().indexOf('USE BOOKSTORE') >= 0)
|
|
95
|
+
{
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
try
|
|
100
|
+
{
|
|
101
|
+
await tmpPool.query(tmpBatch);
|
|
102
|
+
console.log(` Batch ${i + 1}: OK`);
|
|
103
|
+
}
|
|
104
|
+
catch (pError)
|
|
105
|
+
{
|
|
106
|
+
console.error(` Batch ${i + 1}: ERROR - ${pError.message}`);
|
|
107
|
+
console.error(` SQL: ${tmpBatch.substring(0, 100)}...`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log('Database initialization complete.');
|
|
112
|
+
}
|
|
113
|
+
catch (pError)
|
|
114
|
+
{
|
|
115
|
+
console.error(`Fatal error: ${pError.message}`);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
finally
|
|
119
|
+
{
|
|
120
|
+
if (tmpPool)
|
|
121
|
+
{
|
|
122
|
+
await tmpPool.close();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
run();
|
|
File without changes
|