11import { Database as BunSqliteDatabase } from "bun:sqlite" ;
22
3- import * as kysely from "kysely" ;
3+ import { Kysely , type Generated , Migrator } from "kysely" ;
44import { BunSqliteDialect } from "kysely-bun-sqlite" ;
55
6- import { DATA_FOLDER } from "./metadata.ts" ;
7- import { type Pos2D } from "./model.ts" ;
6+ import { DATA_FOLDER } from "../metadata.ts" ;
7+ import Migrations from "./migrations.ts" ;
8+ import { type Pos2D } from "../model.ts" ;
89
9- let database : kysely . Kysely < Database > | null = null ;
10+ let database : Kysely < Database > | null = null ;
1011
1112export interface Database {
1213 chunk_data : {
@@ -18,17 +19,17 @@ export interface Database {
1819 world : string ;
1920 chunk_x : number ;
2021 chunk_z : number ;
21- gen_region_x : kysely . Generated < number > ;
22- gen_region_z : kysely . Generated < number > ;
23- gen_region_coord : kysely . Generated < string > ;
22+ gen_region_x : Generated < number > ;
23+ gen_region_z : Generated < number > ;
24+ gen_region_coord : Generated < string > ;
2425 uuid : string ;
2526 ts : number ;
2627 hash : Buffer ;
2728 } ;
2829}
2930
3031export function get ( ) {
31- return ( database ??= new kysely . Kysely < Database > ( {
32+ return ( database ??= new Kysely < Database > ( {
3233 dialect : new BunSqliteDialect ( {
3334 database : new BunSqliteDatabase (
3435 Bun . env [ "SQLITE_PATH" ] ?? `${ DATA_FOLDER } /db.sqlite` ,
@@ -41,62 +42,20 @@ export function get() {
4142 } ) ) ;
4243}
4344
45+ export function getMigrations ( ) : Migrator {
46+ return new Migrator ( {
47+ db : get ( ) ,
48+ provider : new Migrations ( ) ,
49+ } ) ;
50+ }
51+
52+ /** Convenience function to migrate to latest */
4453export async function setup ( ) {
45- await get ( )
46- . transaction ( )
47- . execute ( async ( db ) => {
48- await db . schema
49- . createTable ( "chunk_data" )
50- . ifNotExists ( )
51- . addColumn ( "hash" , "blob" , ( col ) => col . notNull ( ) . primaryKey ( ) )
52- . addColumn ( "version" , "integer" , ( col ) => col . notNull ( ) )
53- . addColumn ( "data" , "blob" , ( col ) => col . notNull ( ) )
54- . execute ( ) ;
55- await db . schema
56- . createTable ( "player_chunk" )
57- . ifNotExists ( )
58- . addColumn ( "world" , "text" , ( col ) => col . notNull ( ) )
59- . addColumn ( "chunk_x" , "integer" , ( col ) => col . notNull ( ) )
60- . addColumn ( "chunk_z" , "integer" , ( col ) => col . notNull ( ) )
61- . addColumn ( "gen_region_x" , "integer" , ( col ) =>
62- col
63- . generatedAlwaysAs (
64- kysely . sql < number > `floor(chunk_x / 32.0)` ,
65- )
66- . notNull ( ) ,
67- )
68- . addColumn ( "gen_region_z" , "integer" , ( col ) =>
69- col
70- . generatedAlwaysAs (
71- kysely . sql < number > `floor(chunk_z / 32.0)` ,
72- )
73- . notNull ( ) ,
74- )
75- . addColumn ( "gen_region_coord" , "text" , ( col ) => {
76- return col
77- . generatedAlwaysAs (
78- kysely . sql < string > `gen_region_x || '_' || gen_region_z` ,
79- )
80- . notNull ( ) ;
81- } )
82- . addColumn ( "uuid" , "text" , ( col ) => col . notNull ( ) )
83- . addColumn ( "ts" , "bigint" , ( col ) => col . notNull ( ) )
84- . addColumn ( "hash" , "blob" , ( col ) => col . notNull ( ) )
85- . addPrimaryKeyConstraint ( "PK_coords_and_player" , [
86- "world" ,
87- "chunk_x" ,
88- "chunk_z" ,
89- "uuid" ,
90- ] )
91- . addForeignKeyConstraint (
92- "FK_chunk_ref" ,
93- [ "hash" ] ,
94- "chunk_data" ,
95- [ "hash" ] ,
96- ( fk ) => fk . onUpdate ( "no action" ) . onDelete ( "no action" ) ,
97- )
98- . execute ( ) ;
99- } ) ;
54+ const results = await getMigrations ( ) . migrateToLatest ( ) ;
55+ if ( results . error ) {
56+ throw results . error ;
57+ }
58+ return results . results ?? [ ] ;
10059}
10160
10261/**
@@ -178,13 +137,13 @@ export async function storeChunkData(
178137) {
179138 await get ( )
180139 . transaction ( )
181- . execute ( async ( db ) => {
182- await db
140+ . execute ( async ( transaction ) => {
141+ await transaction
183142 . insertInto ( "chunk_data" )
184143 . values ( { hash, version, data } )
185144 . onConflict ( ( oc ) => oc . column ( "hash" ) . doNothing ( ) )
186145 . execute ( ) ;
187- await db
146+ await transaction
188147 . replaceInto ( "player_chunk" )
189148 . values ( {
190149 world : dimension ,
@@ -210,16 +169,16 @@ export async function getRegionChunks(
210169 . selectFrom ( "player_chunk" )
211170 . innerJoin ( "chunk_data" , "chunk_data.hash" , "player_chunk.hash" )
212171 . select ( [
213- "player_chunk.chunk_x as chunk_x " ,
214- "player_chunk.chunk_z as chunk_z " ,
172+ "player_chunk.chunk_x as chunkX " ,
173+ "player_chunk.chunk_z as chunkZ " ,
215174 ( eb ) => eb . fn . max ( "player_chunk.ts" ) . as ( "timestamp" ) ,
216175 "chunk_data.version as version" ,
217176 "chunk_data.data as data" ,
218177 ] )
219178 . where ( "player_chunk.world" , "=" , dimension )
220179 . where ( "player_chunk.gen_region_x" , "=" , regionX )
221180 . where ( "player_chunk.gen_region_z" , "=" , regionZ )
222- . groupBy ( [ "chunk_x " , "chunk_z " , "version" , "data" ] )
223- . orderBy ( "player_chunk.ts " , "desc" )
181+ . groupBy ( [ "chunkX " , "chunkZ " , "version" , "data" ] )
182+ . orderBy ( "timestamp " , "desc" )
224183 . execute ( ) ;
225184}
0 commit comments