Skip to content

Commit 88a6fbe

Browse files
authored
add more details for next js doc (#107)
1 parent 2bfac5f commit 88a6fbe

File tree

1 file changed

+126
-29
lines changed

1 file changed

+126
-29
lines changed

sqlite-cloud/quick-start-next.mdx

Lines changed: 126 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,54 +22,151 @@ npx create-next-app@latest sqlc-quickstart --js --no-tailwind --eslint --app --s
2222
```bash
2323
cd sqlc-quickstart && npm install @sqlitecloud/drivers
2424
```
25-
4. **Query data**
26-
- Replace the code in ```layout.js``` and ```page.js``` with the following snippets.
27-
- Click a node in your account dashboard and copy the connection string. Replace ```<your-connection-string>``` in ```page.js``` with your connection string.
25+
4. **Instantiate a connection**
26+
- The Database driver establishes a TLS connection when used in Node.js, and a websocket connection when used in the browser.
27+
- It is recommended that you use the Database driver in client-side components.
28+
- To share the connection across pages, you can instantiate the connection in a context provider with the ```use client``` directive. Below is a simplified sample implementation.
2829

29-
In ```src/app/layout.js```:
30-
```jsx
31-
export const metadata = {
32-
title: 'Create Next App',
33-
description: 'Generated by create next app',
34-
};
30+
```tsx
31+
// src/app/context/DatabaseContext.tsx
32+
'use client';
33+
34+
import { Database } from '@sqlitecloud/drivers';
35+
import { createContext, useContext, useEffect, useRef, useState } from 'react';
36+
37+
interface DatabaseContextType {
38+
db: Database | null;
39+
isConnecting: boolean;
40+
error: Error | null;
41+
}
42+
43+
const DatabaseContext = createContext<DatabaseContextType | undefined>(undefined);
44+
45+
interface DatabaseProviderProps {
46+
children: React.ReactNode;
47+
config: { connectionString: string }
48+
}
49+
50+
export function DatabaseProvider({ children, config }: DatabaseProviderProps) {
51+
const [isConnecting, setIsConnecting] = useState(true);
52+
const [error, setError] = useState<Error | null>(null);
53+
const dbRef = useRef<Database | null>(null);
54+
55+
useEffect(() => {
56+
if (dbRef.current) return; // Connection already exists
57+
58+
try {
59+
dbRef.current = new Database(config.connectionString);
60+
61+
// Handle connection events
62+
dbRef.current.on('open', () => {
63+
console.log('open')
64+
setIsConnecting(false);
65+
setError(null);
66+
});
67+
68+
dbRef.current.on('error', (err: Error) => {
69+
console.log('error')
70+
setError(err);
71+
setIsConnecting(false);
72+
});
73+
74+
dbRef.current.on('close', () => {
75+
console.log('closing')
76+
setIsConnecting(false);
77+
dbRef.current = null;
78+
});
79+
80+
} catch (err) {
81+
setError(err instanceof Error ? err : new Error('Failed to initialize database'));
82+
setIsConnecting(false);
83+
}
3584

85+
// Cleanup function
86+
return () => {
87+
if (dbRef.current) {
88+
dbRef.current.close();
89+
dbRef.current = null;
90+
}
91+
};
92+
}, [config]);
93+
94+
return (
95+
<DatabaseContext.Provider
96+
value={{
97+
db: dbRef.current,
98+
isConnecting,
99+
error
100+
}}
101+
>
102+
{children}
103+
</DatabaseContext.Provider>
104+
);
105+
}
106+
107+
export function useDatabaseConnection() {
108+
const context = useContext(DatabaseContext);
109+
110+
if (context === undefined) {
111+
throw new Error('useDatabaseConnection must be used within a DatabaseProvider');
112+
}
113+
114+
return context;
115+
}
116+
```
117+
5. **Query data**
118+
- Click the ```Connect``` button in your account dashboard and copy the connection string. Replace ```<your-connection-string>``` in ```page.js``` with your connection string.
119+
- Replace the code in ```layout.js``` and ```page.js``` with the following snippets.
120+
121+
```jsx
122+
// src/app/layout.js
36123
export default function RootLayout({ children }) {
37124
return (
38125
<html lang="en">
39-
<body>{children}</body>
126+
<body>
127+
<DatabaseProvider config={{ connectionString: '<your-connection-string>' }}>
128+
{children}
129+
</DatabaseProvider>
130+
</body>
40131
</html>
41132
);
42133
}
43134
```
44135

45-
In ```src/app/page.js```:
46136
```jsx
47-
import { Database } from '@sqlitecloud/drivers';
48-
49-
async function getAlbums() {
50-
const db = new Database('<your-connection-string>');
137+
// src/app/page.js
138+
import { useDatabaseConnection } from './context/DatabaseContext';
139+
import { useEffect, useState } from "react";
140+
import { useDatabaseConnection } from "./useDatabaseConnection";
51141

52-
const result = await db.sql`USE DATABASE chinook.sqlite;
53-
SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist
54-
FROM albums
55-
INNER JOIN artists
56-
WHERE artists.ArtistId = albums.ArtistId
57-
LIMIT 20;`;
142+
export default function Home() {
143+
const { db } = useDatabaseConnection();
144+
const [albums, setAlbums] = useState<any[]>([]);
58145

59-
return result;
60-
}
146+
useEffect(() => {
147+
const getAlbums = async () => {
148+
const result = await db.sql`USE DATABASE chinook.sqlite;
149+
SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist
150+
FROM albums
151+
INNER JOIN artists
152+
WHERE artists.ArtistId = albums.ArtistId
153+
LIMIT 20;`;
154+
return result;
155+
};
61156

62-
export default async function Home() {
63-
const res = await getAlbums();
157+
if (db) {
158+
getAlbums().then((result) => {
159+
setAlbums(result);
160+
});
161+
}
162+
}, [db]);
64163

65164
return (
66165
<div>
67166
<h1>Albums</h1>
68167
<ul>
69-
{res.map(({ id, title, artist }) => (
70-
<li key={id}>
71-
{title} by {artist}
72-
</li>
168+
{albums.map((album) => (
169+
<div key={album.id}>{album.title}</div>
73170
))}
74171
</ul>
75172
</div>

0 commit comments

Comments
 (0)