Skip to content

Commit d8105d8

Browse files
Merge pull request #219 from sqlitecloud/fix-connection-errors
fix(connection): improve connection management
2 parents 9745f50 + 12c129f commit d8105d8

File tree

23 files changed

+264
-219
lines changed

23 files changed

+264
-219
lines changed

.github/dependabot.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
33
version: 2
44
updates:
5-
- package-ecosystem: "npm"
6-
directory: "/" # Location of package.json
5+
- package-ecosystem: 'npm'
6+
directory: '/' # Location of package.json
77
schedule:
8-
interval: "weekly"
8+
interval: 'weekly'
9+
groups:
10+
all-dependencies:
11+
patterns:
12+
- '*'
913
# Always increase the version requirement
1014
# to match the new version.
1115
versioning-strategy: increase

.github/workflows/test.yml

+17-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ on:
33
push:
44
workflow_dispatch:
55

6+
concurrency:
7+
group: all
8+
cancel-in-progress: true
9+
610
env:
711
DATABASE_URL: ${{ secrets.CHINOOK_DATABASE_URL }}
812

@@ -81,7 +85,7 @@ jobs:
8185
node_test=$(curl localhost:3000)
8286
if [[ $node_test == *"{\"tracks\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
8387
echo "✅ node with-javascript-express test passed"
84-
npx kill-port 3000
88+
npx kill-port 3000 -y
8589
exit 0
8690
fi
8791
echo "❌ node with-javascript-express test failed"
@@ -98,7 +102,7 @@ jobs:
98102
bun_test=$(curl localhost:3000)
99103
if [[ $bun_test == *"{\"tracks\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
100104
echo "✅ bun with-javascript-express test passed"
101-
npx kill-port 3000
105+
npx kill-port 3000 -y
102106
exit 0
103107
fi
104108
echo "❌ bun with-javascript-express test failed"
@@ -112,7 +116,7 @@ jobs:
112116
deno_test=$(curl localhost:3000)
113117
if [[ $deno_test == *"{\"tracks\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
114118
echo "✅ deno with-javascript-express test passed"
115-
npx kill-port 3000
119+
npx kill-port 3000 -y
116120
exit 0
117121
fi
118122
echo "❌ deno with-javascript-express test failed"
@@ -224,14 +228,14 @@ jobs:
224228
working-directory: examples/with-typescript-nextjs
225229
run: |
226230
npm i
227-
npm run dev &
231+
npx next dev -p 3005 &
228232
sleep 3
229-
node_test=$(curl localhost:3003)
230-
node_test2=$(curl localhost:3003/api/hello)
233+
node_test=$(curl localhost:3005)
234+
node_test2=$(curl localhost:3005/api/hello)
231235
232236
if [[ $node_test == *"next.js json route"* && $node_test2 == *"{\"data\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
233237
echo "✅ node with-typescript-nextjs test passed"
234-
npx kill-port 3003
238+
npx kill-port 3005 -y
235239
exit 0
236240
fi
237241
echo "❌ node with-typescript-nextjs test failed"
@@ -243,13 +247,13 @@ jobs:
243247
if [ "$RUNNER_OS" != "Windows" ]; then
244248
bun i #re-installing dependencies in windows with bash causes a panic
245249
fi
246-
bun run dev &
250+
bun next dev -p 3004 &
247251
sleep 3
248-
bun_test=$(curl localhost:3003)
249-
bun_test2=$(curl localhost:3003/api/hello)
252+
bun_test=$(curl localhost:3004)
253+
bun_test2=$(curl localhost:3004/api/hello)
250254
if [[ $bun_test == *"next.js json route"* && $bun_test2 == *"{\"data\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
251255
echo "✅ bun with-typescript-nextjs test passed"
252-
npx kill-port 3003
256+
npx kill-port 3004 -y
253257
exit 0
254258
fi
255259
echo "❌ bun with-typescript-nextjs test failed"
@@ -264,13 +268,14 @@ jobs:
264268
deno_test=$(curl localhost:3003/api/hello)
265269
if [[ $deno_test == *"{\"data\":[{\"TrackId\":1,\"Name\":\"For Those About To Rock (We Salute You)\",\"AlbumId\":1,\"MediaTypeId\":1,\"GenreId\":1,\"Composer\":\"Angus Young, Malcolm Young, Brian Johnson\",\"Milliseconds\":343719,\"Bytes\":11170334,\"UnitPrice\":0.99},{"* ]]; then
266270
echo "✅ deno with-typescript-nextjs test passed"
267-
npx kill-port 3003
271+
npx kill-port 3003 -y
268272
exit 0
269273
fi
270274
echo "❌ deno with-typescript-nextjs test failed"
271275
exit 1
272276
273277
- name: remove with-typescript-nextjs
278+
if: matrix.os != 'ubuntu-latest' #rm: cannot remove examples/with-typescript-nextjs: Directory not empty
274279
run: rm -rf examples/with-typescript-nextjs
275280

276281
- name: node with-javascript-vite

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let database = new Database('sqlitecloud://user:[email protected]:8860/c
5454

5555
let name = 'Breaking The Rules'
5656

57-
let results = await database.sql`SELECT * FROM tracks WHERE name = ${name}`
57+
let results = await database.sql('SELECT * FROM tracks WHERE name = ?', name)
5858
// => returns [{ AlbumId: 1, Name: 'Breaking The Rules', Composer: 'Angus Young... }]
5959
```
6060

@@ -82,7 +82,7 @@ await pubSub.listen(PUBSUB_ENTITY_TYPE.TABLE, 'albums', (error, results, data) =
8282
}
8383
})
8484

85-
await database.sql`INSERT INTO albums (Title, ArtistId) values ('Brand new song', 1)`
85+
await database.sql("INSERT INTO albums (Title, ArtistId) values ('Brand new song', 1)")
8686

8787
// Stop listening changes on the table
8888
await pubSub.unlisten(PUBSUB_ENTITY_TYPE.TABLE, 'albums')

examples/with-javascript-browser/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h2 class="pb-4">Results:</h2>
4848
var database = null;
4949

5050
sendButton.addEventListener('click', () => {
51-
if (!database) {
51+
if (!database || !database.isConnected()) {
5252
// Get the input element by ID
5353
var connectionStringinputElement = document.getElementById('connectionStringInput');
5454
var connectionstring = connectionStringinputElement.value;

examples/with-javascript-expo/components/AddTaskModal.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
22
import { View, StyleSheet, Alert, Platform } from "react-native";
33
import { TextInput, Button, Modal } from "react-native-paper";
44
import DropdownMenu from "./DropdownMenu";
5-
import db from "../db/dbConnection";
5+
import getDbConnection from "../db/dbConnection";
66

77
export default AddTaskModal = ({
88
modalVisible,
@@ -30,7 +30,7 @@ export default AddTaskModal = ({
3030

3131
const getTags = async () => {
3232
try {
33-
const tags = await db.sql("SELECT * FROM tags");
33+
const tags = await getDbConnection().sql("SELECT * FROM tags");
3434
setTagsList(tags);
3535
} catch (error) {
3636
console.error("Error getting tags", error);
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
import { DATABASE_URL } from "@env";
22
import { Database } from "@sqlitecloud/drivers";
33

4-
export default db = new Database(DATABASE_URL);
4+
/**
5+
* @type {Database}
6+
*/
7+
let database = null;
8+
9+
export default function getDbConnection() {
10+
if (!database || !database.isConnected()) {
11+
database = new Database(DATABASE_URL);
12+
}
13+
return database;
14+
}

examples/with-javascript-expo/hooks/useCategories.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useState, useEffect } from "react";
2-
import db from "../db/dbConnection";
2+
import getDbConnection from "../db/dbConnection";
33

44
const useCategories = () => {
55
const [moreCategories, setMoreCategories] = useState(["Work", "Personal"]);
66

77
const getCategories = async () => {
88
try {
9-
const tags = await db.sql("SELECT * FROM tags");
9+
const tags = await getDbConnection().sql("SELECT * FROM tags");
1010
const filteredTags = tags.filter((tag) => {
1111
return tag["name"] !== "Work" && tag["name"] !== "Personal";
1212
});
@@ -21,7 +21,7 @@ const useCategories = () => {
2121

2222
const addCategory = async (newCategory) => {
2323
try {
24-
await db.sql(
24+
await getDbConnection().sql(
2525
"INSERT INTO tags (name) VALUES (?) RETURNING *",
2626
newCategory
2727
);
@@ -33,15 +33,15 @@ const useCategories = () => {
3333

3434
const initializeTables = async () => {
3535
try {
36-
const createTasksTable = await db.sql(
36+
const createTasksTable = await getDbConnection().sql(
3737
"CREATE TABLE IF NOT EXISTS tasks (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, isCompleted INT NOT NULL);"
3838
);
3939

40-
const createTagsTable = await db.sql(
40+
const createTagsTable = await getDbConnection().sql(
4141
"CREATE TABLE IF NOT EXISTS tags (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, UNIQUE(name));"
4242
);
4343

44-
const createTagsTasksTable = await db.sql(
44+
const createTagsTasksTable = await getDbConnection().sql(
4545
"CREATE TABLE IF NOT EXISTS tasks_tags (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, task_id INTEGER NOT NULL, tag_id INTEGER NOT NULL, FOREIGN KEY (task_id) REFERENCES tasks(id), FOREIGN KEY (tag_id) REFERENCES tags(id));"
4646
);
4747

@@ -52,8 +52,8 @@ const useCategories = () => {
5252
) {
5353
console.log("Successfully created tables");
5454

55-
await db.sql("INSERT OR IGNORE INTO tags (name) VALUES (?)", "Work");
56-
await db.sql(
55+
await getDbConnection().sql("INSERT OR IGNORE INTO tags (name) VALUES (?)", "Work");
56+
await getDbConnection().sql(
5757
"INSERT OR IGNORE INTO tags (name) VALUES (?)",
5858
"Personal"
5959
);

examples/with-javascript-expo/hooks/useTasks.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState, useEffect, useCallback } from "react";
2-
import db from "../db/dbConnection";
2+
import getDbConnection from "../db/dbConnection";
33

44
const useTasks = (tag = null) => {
55
const [taskList, setTaskList] = useState([]);
@@ -8,7 +8,7 @@ const useTasks = (tag = null) => {
88
try {
99
let result;
1010
if (tag) {
11-
result = await db.sql(
11+
result = await getDbConnection().sql(
1212
`
1313
SELECT tasks.*, tags.id AS tag_id, tags.name AS tag_name
1414
FROM tasks
@@ -19,11 +19,11 @@ const useTasks = (tag = null) => {
1919
);
2020
setTaskList(result);
2121
} else {
22-
result = await db.sql`
22+
result = await getDbConnection().sql(`
2323
SELECT tasks.*, tags.id AS tag_id, tags.name AS tag_name
2424
FROM tasks
2525
JOIN tasks_tags ON tasks.id = tasks_tags.task_id
26-
JOIN tags ON tags.id = tasks_tags.tag_id`;
26+
JOIN tags ON tags.id = tasks_tags.tag_id`);
2727
setTaskList(result);
2828
}
2929
} catch (error) {
@@ -33,7 +33,7 @@ const useTasks = (tag = null) => {
3333

3434
const updateTask = async (completedStatus, taskId) => {
3535
try {
36-
await db.sql(
36+
await getDbConnection().sql(
3737
"UPDATE tasks SET isCompleted=? WHERE id=? RETURNING *",
3838
completedStatus,
3939
taskId
@@ -47,21 +47,21 @@ const useTasks = (tag = null) => {
4747
const addTaskTag = async (newTask, tag) => {
4848
try {
4949
if (tag.id) {
50-
const addNewTask = await db.sql(
50+
const addNewTask = await getDbConnection().sql(
5151
"INSERT INTO tasks (title, isCompleted) VALUES (?, ?) RETURNING *",
5252
newTask.title,
5353
newTask.isCompleted
5454
);
5555
addNewTask[0].tag_id = tag.id;
5656
addNewTask[0].tag_name = tag.name;
5757
setTaskList([...taskList, addNewTask[0]]);
58-
await db.sql(
58+
await getDbConnection().sql(
5959
"INSERT INTO tasks_tags (task_id, tag_id) VALUES (?, ?)",
6060
addNewTask[0].id,
6161
tag.id
6262
);
6363
} else {
64-
const addNewTaskNoTag = await db.sql(
64+
const addNewTaskNoTag = await getDbConnection().sql(
6565
"INSERT INTO tasks (title, isCompleted) VALUES (?, ?) RETURNING *",
6666
newTask.title,
6767
newTask.isCompleted
@@ -75,8 +75,8 @@ const useTasks = (tag = null) => {
7575

7676
const deleteTask = async (taskId) => {
7777
try {
78-
await db.sql("DELETE FROM tasks_tags WHERE task_id=?", taskId);
79-
const result = await db.sql("DELETE FROM tasks WHERE id=?", taskId);
78+
await getDbConnection().sql("DELETE FROM tasks_tags WHERE task_id=?", taskId);
79+
const result = await getDbConnection().sql("DELETE FROM tasks WHERE id=?", taskId);
8080
console.log(`Deleted ${result.totalChanges} task`);
8181
getTasks();
8282
} catch (error) {

examples/with-javascript-express/app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ app.use(express.json())
1515
/* http://localhost:3001/ returns chinook tracks as json */
1616
app.get('/', async function (req, res, next) {
1717
var database = new sqlitecloud.Database(DATABASE_URL)
18-
var tracks = await database.sql`USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;`
18+
var tracks = await database.sql('USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;')
1919
res.send({ tracks })
2020
})
2121

examples/with-javascript-vite/src/App.jsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
import { useEffect, useState } from "react";
22
import { Database } from "@sqlitecloud/drivers";
33

4-
const db = new Database(import.meta.env.VITE_DATABASE_URL);
4+
let db = null
5+
6+
function getDatabase() {
7+
if (!db || !db.isConnected()) {
8+
db = new Database(import.meta.env.VITE_DATABASE_URL);
9+
}
10+
11+
return db;
12+
}
13+
514

615
function App() {
716
const [data, setData] = useState([]);
817

918
const getAlbums = async () => {
10-
const result = await db.sql`
19+
const result = await getDatabase().sql(`
1120
USE DATABASE chinook.sqlite;
1221
SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist
1322
FROM albums
1423
INNER JOIN artists
1524
WHERE artists.ArtistId = albums.ArtistId
1625
LIMIT 20;
17-
`;
26+
`);
1827
setData(result);
1928
};
2029

examples/with-plain-javascript/app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ async function selectTracks() {
1313
var database = new sqlitecloud.Database(DATABASE_URL)
1414

1515
// run async query
16-
var tracks = await database.sql`USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;`
16+
var tracks = await database.sql('USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;')
1717
console.log(`selectTracks returned:`, tracks)
1818

1919
// You can also use all the regular sqlite3 api with callbacks, see:

examples/with-typescript-nextjs/app/api/hello/route.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export async function GET(request: NextRequest) {
1515
const database = new Database(DATABASE_URL)
1616

1717
// retrieve rows from chinook database using a plain SQL query
18-
const tracks = await database.sql`USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;`
18+
const tracks = await database.sql('USE DATABASE chinook.sqlite; SELECT * FROM tracks LIMIT 20;')
1919

2020
// return as json response
2121
return NextResponse.json<{ data: any }>({ data: tracks })

examples/with-typescript-nextjs/app/page.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Image from 'next/image'
21
import styles from './page.module.css'
32

43
export default function Home() {

examples/with-typescript-react-native/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default function App() {
1111
const db = new Database(`${DATABASE_URL}`);
1212

1313
const result =
14-
await db.sql`USE DATABASE chinook.sqlite; SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist FROM albums INNER JOIN artists WHERE artists.ArtistId = albums.ArtistId LIMIT 20;`;
14+
await db.sql('USE DATABASE chinook.sqlite; SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist FROM albums INNER JOIN artists WHERE artists.ArtistId = albums.ArtistId LIMIT 20;');
1515

1616
setAlbums(result);
1717
}

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sqlitecloud/drivers",
3-
"version": "1.0.417",
3+
"version": "1.0.422",
44
"description": "SQLiteCloud drivers for Typescript/Javascript in edge, web and node clients",
55
"main": "./lib/index.js",
66
"types": "./lib/index.d.ts",

0 commit comments

Comments
 (0)