Skip to content

Commit 9623820

Browse files
authored
feat: PE-968: Create SQLlite brightscript example for Barrows (#85)
- Add an example app that combines BrightScript and JavaScript to handle SQLite database operations
1 parent 3da13eb commit 9623820

File tree

4 files changed

+233
-1
lines changed

4 files changed

+233
-1
lines changed

.husky/common.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
command_exists () {
2+
command -v "$1" >/dev/null 2>&1
3+
}
4+
5+
# Workaround for Windows 10, Git Bash, and Yarn
6+
if command_exists winpty && test -t 1; then
7+
exec < /dev/tty
8+
fi

.husky/prepare-commit-msg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/usr/bin/env sh
22
. "$(dirname -- "$0")/_/husky.sh"
33

4-
exec < /dev/tty && npx cz --hook || true
4+
. .husky/common.sh
5+
6+
npx cz --hook || true
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
' autorun.brs - BrightScript example for SQLite DB usage
2+
' This script demonstrates creating a DB, inserting, reading,
3+
' deleting records, and closing the DB.
4+
5+
Sub Main()
6+
port = CreateObject("roMessagePort")
7+
m.nodejs = CreateObject("roNodeJs", "SD:/index.js", { message_port: port })
8+
9+
dbPath$ = "SD:/example.db"
10+
11+
' Event Loop
12+
while true
13+
ev = wait(0, port)
14+
' print "=== BS: Received event ";type(ev)
15+
if type(ev) = "roNodeJsEvent" then
16+
eventData = ev.GetData()
17+
if type(eventData) = "roAssociativeArray" and type(eventData.reason) = "roString" then
18+
if eventData.reason = "process_exit" then
19+
print "=== BS: Node.js instance exited with code " ; eventData.exit_code
20+
if m.db <> invalid then
21+
m.db.Close()
22+
print "Database closed."
23+
end if
24+
25+
else if eventData.reason = "message" then
26+
print "=== BS: Received message from JS app: "; eventData.message
27+
28+
if type(eventData.message) = "roAssociativeArray" then
29+
if eventData.message.action = "ready" then
30+
print "=== index.js loaded: "; eventData.message.message
31+
32+
' Create the SQLite database
33+
m.db = CreateObject("roSqliteDatabase")
34+
m.db.SetPort(port)
35+
if m.db.Create(dbPath$) then
36+
m.nodejs.PostJSMessage({ action: "dbCreated", path: dbPath$ })
37+
else
38+
print "Failed to create database. Exiting."
39+
stop
40+
end if
41+
else if eventData.message.action = "create" then
42+
createOk = CreateTable(eventData.message.command)
43+
if not createOk then
44+
print "Failed to create table: "; eventData.message.command
45+
stop
46+
end if
47+
else if eventData.message.action = "insert" then
48+
insertOk = InsertRecords(eventData.message.command)
49+
if not insertOk then
50+
print "Failed to insert record: "; eventData.message.command
51+
stop
52+
end if
53+
else if eventData.message.action = "select" then
54+
records = SelectRecords(eventData.message.command)
55+
if records = invalid then
56+
print "Failed to retrieve records: "; eventData.message.command
57+
stop
58+
end if
59+
else if eventData.message.action = "delete" then
60+
deleteOk = DeleteRecord(eventData.message.command)
61+
if not deleteOk then
62+
print "Failed to delete record: "; eventData.message.command
63+
stop
64+
end if
65+
else
66+
print "=== BS: Unknown action: "; eventData.message.action
67+
end if
68+
else
69+
print "=== BS: Unknown message type: "; type(eventData.message)
70+
end if
71+
else
72+
print "======= UNHANDLED NODEJS EVENT ========="
73+
print eventData.reason
74+
endif
75+
else
76+
print "=== BS: Unknown eventData: "; type(eventData)
77+
endif
78+
endif
79+
end while
80+
end Sub
81+
82+
Function CreateTable(createSQL as string) as boolean
83+
stmt = m.db.CreateStatement(createSQL)
84+
if type(stmt) = "roSqliteStatement" then
85+
result = stmt.Run()
86+
if result <> 100 then
87+
print "Failed to create table."
88+
return false
89+
end if
90+
m.nodejs.PostJSMessage({ action: "create", command: createSQL })
91+
stmt.Finalise()
92+
return true
93+
else
94+
return false
95+
end if
96+
end Function
97+
98+
Function InsertRecords(insertSQL as string) as boolean
99+
insertStmt = m.db.CreateStatement(insertSQL)
100+
if type(insertStmt) = "roSqliteStatement" then
101+
result = insertStmt.Run()
102+
if result <> 100 then
103+
print "Failed to insert record"
104+
return false
105+
end if
106+
m.nodejs.PostJSMessage({ action: "insert", command: insertSQL })
107+
insertStmt.Finalise()
108+
return true
109+
else
110+
return false
111+
end if
112+
end Function
113+
114+
Function SelectRecords(selectSQL as string) as dynamic
115+
stmt = m.db.CreateStatement(selectSQL)
116+
if type(stmt) = "roSqliteStatement" then
117+
sqlResult = stmt.Run()
118+
records = []
119+
while sqlResult = 102
120+
resultsData = stmt.GetData()
121+
records.push(resultsData)
122+
sqlResult = stmt.Run()
123+
end while
124+
125+
' Stringify the records array since the roAssociativeArray sent
126+
' as input to PostJSMessage() cannot contain an roArray type.
127+
resultAsString = FormatJson(records)
128+
m.nodejs.PostJSMessage({ action: "select", command: selectSQL, result: resultAsString })
129+
stmt.Finalise()
130+
return records
131+
else
132+
return invalid
133+
end if
134+
end Function
135+
136+
Function DeleteRecord(deleteSQL as string) as boolean
137+
deleteStmt = m.db.CreateStatement(deleteSQL)
138+
if type(deleteStmt) = "roSqliteStatement" then
139+
result = deleteStmt.Run()
140+
m.nodejs.PostJSMessage({ action: "delete", command: deleteSQL })
141+
deleteStmt.Finalise()
142+
return true
143+
else
144+
return false
145+
end if
146+
end Function
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// index.js - BrightSign JavaScript app to receive messages from BrightScript via MessagePort
2+
3+
const MESSAGE_PORT = require("@brightsign/messageport");
4+
const bsMessage = new MESSAGE_PORT();
5+
6+
if (bsMessage) {
7+
bsMessage.addEventListener('bsmessage', function(msg) {
8+
if (msg && typeof msg === 'object') {
9+
switch(msg.action) {
10+
case 'dbCreated': {
11+
console.log('Database created at:', msg.path);
12+
bsMessage.PostBSMessage({
13+
action: 'create',
14+
command: "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);"
15+
});
16+
break;
17+
}
18+
case 'create': {
19+
console.log('Created table:', msg);
20+
bsMessage.PostBSMessage({
21+
action: 'insert',
22+
command: "INSERT INTO users (name, age) VALUES ('Alice', 25), ('Bob', 30), ('Charlie', 35);"
23+
});
24+
break;
25+
}
26+
case 'insert': {
27+
console.log('Inserted record:', msg);
28+
bsMessage.PostBSMessage({
29+
action: 'select',
30+
command: "SELECT id, name, age FROM users;"
31+
});
32+
break;
33+
}
34+
case 'select': {
35+
console.log('Retrieved records:', msg);
36+
if (typeof msg.result === 'string') {
37+
msg.result = JSON.parse(msg.result);
38+
}
39+
if (Array.isArray(msg.result) && msg.result.length > 0) {
40+
for (const record of msg.result) {
41+
bsMessage.PostBSMessage({
42+
action: 'delete',
43+
command: `DELETE FROM users WHERE id = ${record.id};`
44+
});
45+
}
46+
}
47+
break;
48+
}
49+
case 'delete': {
50+
console.log('Deleted record:', msg);
51+
break;
52+
}
53+
default: {
54+
console.log('Unknown message type:', msg);
55+
break;
56+
}
57+
}
58+
} else {
59+
console.log('Received non-object message:', msg);
60+
}
61+
});
62+
63+
// Send an initial message to indicate the JS app has started.
64+
// This will be received by the BrightScript side
65+
// which will then create the database.
66+
bsMessage.PostBSMessage({
67+
action: 'ready',
68+
message: 'SQLite DB Example app has started.'
69+
});
70+
71+
// Uncomment the line below to keep the JS app running indefinitely.
72+
// setInterval(function(){}, 10000);
73+
74+
} else {
75+
console.log('@brightsign/messageport API not available.');
76+
}

0 commit comments

Comments
 (0)