@@ -2,27 +2,6 @@ import type { Sql } from 'postgres';
22
33let sql : Sql | null = null ;
44
5- export interface IssuesProps {
6- id : string ;
7- title : string ;
8- body : string ;
9- url : string ;
10- labels ?: { nodes : Array < { name : string } > } ;
11- hasVoted ?: boolean ;
12- updated_at : Date ;
13- }
14-
15- export interface VotesProps {
16- id : string ;
17- vote : number ;
18- updated_at : Date ;
19- }
20-
21- export interface UserVotes {
22- userId : string ;
23- issueId : number ;
24- }
25-
265async function dbConnect ( ) {
276 if ( ! sql ) {
287 const postgres = ( await import ( 'postgres' ) ) . default ;
@@ -53,193 +32,4 @@ async function dbConnect() {
5332 return sql ;
5433}
5534
56- async function getVotes ( ) : Promise < VotesProps [ ] > {
57- try {
58- const sql = await dbConnect ( ) ;
59- const votes = await sql `SELECT * FROM votes` ;
60- return votes as unknown as VotesProps [ ] ;
61- } catch {
62- // error
63- console . error ( 'Error load votes from db' ) ;
64- return [ ] ;
65- }
66- }
67-
68- async function getIssues ( ) : Promise < IssuesProps [ ] > {
69- try {
70- const sql = await dbConnect ( ) ;
71- const issues = await sql `SELECT * FROM issues` ;
72- return issues as unknown as IssuesProps [ ] ;
73- } catch {
74- console . error ( 'Error load issues from db' ) ;
75- return [ ] ;
76- }
77- }
78-
79- async function getVote ( id : string ) : Promise < number | null > {
80- try {
81- const sql = await dbConnect ( ) ;
82- const result = await sql `SELECT vote FROM votes WHERE id = ${ id } ` ;
83- if ( result . length === 0 ) {
84- return null ;
85- }
86-
87- return result [ 0 ] . vote as number ;
88- } catch {
89- console . error ( `Error load vote with id ${ id } from db` ) ;
90- return null ;
91- }
92- }
93-
94- async function getUserVoted ( userId : string ) : Promise < string [ ] | null > {
95- try {
96- const sql = await dbConnect ( ) ;
97-
98- const result = await sql `
99- SELECT issue_id FROM user_votes WHERE user_id = ${ userId }
100- ` ;
101-
102- if ( result . length === 0 ) {
103- return null ;
104- }
105-
106- return result . map ( ( row ) => row . issue_id ) ;
107- } catch {
108- console . error ( 'Error load user votes from db' ) ;
109- return null ;
110- }
111- }
112-
113- async function incrementVote ( issueId : string , userId : string ) : Promise < boolean > {
114- try {
115- const sql = await dbConnect ( ) ;
116- const userVoted = await addUserVote ( userId , issueId ) ;
117-
118- if ( ! userVoted ) {
119- return false ;
120- }
121-
122- const result = await sql `
123- INSERT INTO votes (id, vote, updated_at)
124- VALUES (${ issueId } , 1, ${ new Date ( ) . toISOString ( ) } )
125- ON CONFLICT (id) DO UPDATE SET vote = votes.vote + 1, updated_at = ${ new Date ( ) . toISOString ( ) }
126- RETURNING *
127- ` ;
128-
129- if ( result . length < 1 ) {
130- return false ;
131- }
132-
133- return true ;
134- } catch {
135- return false ;
136- }
137- }
138-
139- async function decrementVote ( issueId : string , userId : string ) : Promise < boolean > {
140- try {
141- const sql = await dbConnect ( ) ;
142- const userVoted = await removeUserVote ( userId , issueId ) ;
143-
144- if ( ! userVoted ) {
145- return false ;
146- }
147-
148- const result = await sql `
149- UPDATE votes
150- SET vote = CASE WHEN vote > 0 THEN vote - 1 ELSE 0 END, updated_at = ${ new Date ( ) . toISOString ( ) }
151- WHERE id = ${ issueId }
152- RETURNING *
153- ` ;
154-
155- if ( result . length < 1 ) {
156- return false ;
157- }
158-
159- return true ;
160- } catch {
161- return false ;
162- }
163- }
164-
165- async function addUserVote ( userId : string , issueId : string ) : Promise < boolean > {
166- try {
167- const sql = await dbConnect ( ) ;
168- const result = await sql `
169- INSERT INTO user_votes (user_id, issue_id)
170- VALUES (${ userId } , ${ issueId } )
171- RETURNING *
172- ` ;
173-
174- if ( result . length < 1 ) {
175- return false ;
176- }
177-
178- return true ;
179- } catch {
180- return false ;
181- }
182- }
183-
184- async function removeUserVote ( userId : string , issueId : string ) : Promise < boolean > {
185- try {
186- const sql = await dbConnect ( ) ;
187- const result = await sql `
188- DELETE FROM user_votes
189- WHERE user_id = ${ userId } AND issue_id = ${ issueId }
190- RETURNING *
191- ` ;
192-
193- if ( result . length < 1 ) {
194- return false ;
195- }
196-
197- return true ;
198- } catch {
199- return false ;
200- }
201- }
202-
203- async function refreshIssues ( issues : object ) : Promise < boolean > {
204- const updated_at = new Date ( ) . toISOString ( ) ;
205-
206- try {
207- const sql = await dbConnect ( ) ;
208- await sql `TRUNCATE TABLE issues RESTART IDENTITY` ;
209-
210- if ( ! Array . isArray ( issues ) ) {
211- throw new Error ( 'Source must be an array of issues' ) ;
212- }
213-
214- for ( const issue of issues ) {
215- if ( typeof issue !== 'object' || ! issue . id || ! issue . title || ! issue . url ) {
216- throw new TypeError ( 'Each issue must be an object with id and url' ) ;
217- }
218- // Ensure issue has the required properties
219- if ( ! issue . body ) {
220- issue . body = '' ;
221- }
222-
223- // Insert each issue into the database
224- await sql `INSERT INTO issues (id, title, body, url, updated_at) VALUES (${ issue . id } , ${ issue . title } , ${ issue . body } , ${ issue . url } , ${ updated_at } )` ;
225- }
226-
227- return true ;
228- } catch {
229- console . error ( 'Error caching issues to db' ) ;
230- return false ;
231- }
232- }
233-
234- export {
235- dbConnect ,
236- getVotes ,
237- getUserVoted ,
238- getIssues ,
239- getVote ,
240- incrementVote ,
241- decrementVote ,
242- refreshIssues ,
243- addUserVote ,
244- removeUserVote ,
245- } ;
35+ export { dbConnect } ;
0 commit comments