1
1
import { Kysely , Migrator } from 'kysely'
2
2
3
- import type { DatabaseDriverName } from '~/db- drivers'
4
- import { getDatabaseDriver } from '~/db- drivers'
3
+ import type { DatabaseDriverName } from '~/lib/db/ drivers'
4
+ import { getDatabaseDriver } from '~/lib/db/ drivers'
5
5
import { migrations } from '~/lib/db/migrations'
6
6
import { ENV } from '~/lib/env'
7
7
import { logger } from '~/lib/logger'
8
8
9
9
import type { Selectable } from 'kysely'
10
10
11
- export interface Database {
12
- cache_keys : CacheKeysTable
13
- }
14
-
15
11
export interface CacheKeysTable {
16
12
key : string
17
13
version : string
18
14
updated_at : string
19
15
accessed_at : string
20
16
}
17
+ export interface UploadsTable {
18
+ created_at : string
19
+ key : string
20
+ version : string
21
+ id : number
22
+ driver_upload_id : string
23
+ }
24
+ export interface UploadPartsTable {
25
+ upload_id : number
26
+ part_number : number
27
+ e_tag : string | null
28
+ }
29
+
30
+ export interface Database {
31
+ cache_keys : CacheKeysTable
32
+ uploads : UploadsTable
33
+ upload_parts : UploadPartsTable
34
+ }
21
35
22
- let db : Kysely < Database >
36
+ let _db : Kysely < Database >
23
37
24
38
export async function initializeDatabase ( ) {
25
39
const driverName = ENV . DB_DRIVER
@@ -33,13 +47,13 @@ export async function initializeDatabase() {
33
47
34
48
const driver = await driverSetup ( )
35
49
36
- db = new Kysely < Database > ( {
50
+ _db = new Kysely < Database > ( {
37
51
dialect : driver ,
38
52
} )
39
53
40
54
logger . info ( 'Migrating database...' )
41
55
const migrator = new Migrator ( {
42
- db,
56
+ db : _db ,
43
57
provider : {
44
58
async getMigrations ( ) {
45
59
return migrations ( driverName as DatabaseDriverName )
@@ -56,15 +70,24 @@ export async function initializeDatabase() {
56
70
logger . success ( 'Database migrated' )
57
71
}
58
72
73
+ export function useDB ( ) {
74
+ return _db
75
+ }
76
+
77
+ type DB = typeof _db
78
+
59
79
/**
60
80
* @see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
61
81
*/
62
- export async function findKeyMatch ( opts : { key : string ; version : string ; restoreKeys ?: string [ ] } ) {
63
- logger . debug ( 'Finding key match' , opts )
82
+ export async function findKeyMatch (
83
+ db : DB ,
84
+ args : { key : string ; version : string ; restoreKeys ?: string [ ] } ,
85
+ ) {
86
+ logger . debug ( 'Finding key match' , args )
64
87
const exactPrimaryMatch = await db
65
88
. selectFrom ( 'cache_keys' )
66
- . where ( 'key' , '=' , opts . key )
67
- . where ( 'version' , '=' , opts . version )
89
+ . where ( 'key' , '=' , args . key )
90
+ . where ( 'version' , '=' , args . version )
68
91
. selectAll ( )
69
92
. executeTakeFirst ( )
70
93
if ( exactPrimaryMatch ) {
@@ -75,8 +98,8 @@ export async function findKeyMatch(opts: { key: string; version: string; restore
75
98
76
99
const prefixedPrimaryMatch = await db
77
100
. selectFrom ( 'cache_keys' )
78
- . where ( 'key' , 'like' , `${ opts . key } %` )
79
- . where ( 'version' , '=' , opts . version )
101
+ . where ( 'key' , 'like' , `${ args . key } %` )
102
+ . where ( 'version' , '=' , args . version )
80
103
. orderBy ( 'cache_keys.updated_at desc' )
81
104
. selectAll ( )
82
105
. executeTakeFirst ( )
@@ -85,16 +108,16 @@ export async function findKeyMatch(opts: { key: string; version: string; restore
85
108
return prefixedPrimaryMatch
86
109
}
87
110
88
- if ( ! opts . restoreKeys ) {
111
+ if ( ! args . restoreKeys ) {
89
112
logger . debug ( 'No restore keys provided' )
90
113
return
91
114
}
92
115
93
- logger . debug ( 'Trying restore keys' , opts . restoreKeys )
94
- for ( const key of opts . restoreKeys ) {
116
+ logger . debug ( 'Trying restore keys' , args . restoreKeys )
117
+ for ( const key of args . restoreKeys ) {
95
118
const exactMatch = await db
96
119
. selectFrom ( 'cache_keys' )
97
- . where ( 'version' , '=' , opts . version )
120
+ . where ( 'version' , '=' , args . version )
98
121
. where ( 'key' , '=' , key )
99
122
. orderBy ( 'cache_keys.updated_at desc' )
100
123
. selectAll ( )
@@ -107,7 +130,7 @@ export async function findKeyMatch(opts: { key: string; version: string; restore
107
130
108
131
const prefixedMatch = await db
109
132
. selectFrom ( 'cache_keys' )
110
- . where ( 'version' , '=' , opts . version )
133
+ . where ( 'version' , '=' , args . version )
111
134
. where ( 'key' , 'like' , `${ key } %` )
112
135
. orderBy ( 'cache_keys.updated_at desc' )
113
136
. selectAll ( )
@@ -121,7 +144,18 @@ export async function findKeyMatch(opts: { key: string; version: string; restore
121
144
}
122
145
}
123
146
124
- export async function updateOrCreateKey ( key : string , version : string , date ?: Date ) {
147
+ export async function updateOrCreateKey (
148
+ db : DB ,
149
+ {
150
+ key,
151
+ version,
152
+ date,
153
+ } : {
154
+ key : string
155
+ version : string
156
+ date ?: Date
157
+ } ,
158
+ ) {
125
159
const now = date ?? new Date ( )
126
160
const updateResult = await db
127
161
. updateTable ( 'cache_keys' )
@@ -131,11 +165,14 @@ export async function updateOrCreateKey(key: string, version: string, date?: Dat
131
165
. where ( 'version' , '=' , version )
132
166
. executeTakeFirst ( )
133
167
if ( Number ( updateResult . numUpdatedRows ) === 0 ) {
134
- await createKey ( key , version , date )
168
+ await createKey ( db , { key, version, date } )
135
169
}
136
170
}
137
171
138
- export async function touchKey ( key : string , version : string , date ?: Date ) {
172
+ export async function touchKey (
173
+ db : DB ,
174
+ { key, version, date } : { key : string ; version : string ; date ?: Date } ,
175
+ ) {
139
176
const now = date ?? new Date ( )
140
177
await db
141
178
. updateTable ( 'cache_keys' )
@@ -145,7 +182,10 @@ export async function touchKey(key: string, version: string, date?: Date) {
145
182
. execute ( )
146
183
}
147
184
148
- export async function findStaleKeys ( olderThanDays : number | undefined , date ?: Date ) {
185
+ export async function findStaleKeys (
186
+ db : DB ,
187
+ { olderThanDays, date } : { olderThanDays ?: number ; date ?: Date } ,
188
+ ) {
149
189
if ( olderThanDays === undefined ) return db . selectFrom ( 'cache_keys' ) . selectAll ( ) . execute ( )
150
190
151
191
const now = date ?? new Date ( )
@@ -157,7 +197,10 @@ export async function findStaleKeys(olderThanDays: number | undefined, date?: Da
157
197
. execute ( )
158
198
}
159
199
160
- export async function createKey ( key : string , version : string , date ?: Date ) {
200
+ export async function createKey (
201
+ db : DB ,
202
+ { key, version, date } : { key : string ; version : string ; date ?: Date } ,
203
+ ) {
161
204
const now = date ?? new Date ( )
162
205
await db
163
206
. insertInto ( 'cache_keys' )
@@ -170,10 +213,10 @@ export async function createKey(key: string, version: string, date?: Date) {
170
213
. execute ( )
171
214
}
172
215
173
- export async function pruneKeys ( keys ?: Selectable < CacheKeysTable > [ ] ) {
216
+ export async function pruneKeys ( db : DB , keys ?: Selectable < CacheKeysTable > [ ] ) {
174
217
if ( keys ) {
175
218
await db . transaction ( ) . execute ( async ( tx ) => {
176
- for ( const { key, version } of keys ) {
219
+ for ( const { key, version } of keys ?? [ ] ) {
177
220
await tx
178
221
. deleteFrom ( 'cache_keys' )
179
222
. where ( 'key' , '=' , key )
@@ -185,3 +228,13 @@ export async function pruneKeys(keys?: Selectable<CacheKeysTable>[]) {
185
228
await db . deleteFrom ( 'cache_keys' ) . execute ( )
186
229
}
187
230
}
231
+
232
+ export async function uploadExists ( db : DB , { key, version } : { key : string ; version : string } ) {
233
+ const row = await db
234
+ . selectFrom ( 'uploads' )
235
+ . select ( 'id' )
236
+ . where ( 'key' , '=' , key )
237
+ . where ( 'version' , '=' , version )
238
+ . executeTakeFirst ( )
239
+ return ! ! row
240
+ }
0 commit comments