22import * as path from 'path' ;
33import * as zlib from 'zlib' ;
44import vscode from 'vscode' ;
5- import { promisify } from 'util' ;
65import { Backtest } from './types' ;
76import { ProjectInfo } from './types' ;
87
@@ -11,154 +10,120 @@ export class Database {
1110 private static instance : Database ;
1211 private db : any ;
1312 private dbPath = '' ;
14- private initialized = false ;
1513 private isLoaded = false ;
1614 private readonly CONFIG_FILE_NAME : string = '.backtest-man' ;
17- private readonly gzip = promisify ( zlib . gzip ) ;
18- private readonly gunzip = promisify ( zlib . gunzip ) ;
1915
2016 private constructor ( ) { }
2117
2218 public static getInstance ( workspacePath : string ) : Database {
2319 if ( ! Database . instance ) {
2420 Database . instance = new Database ( ) ;
2521 Database . instance . initialize ( workspacePath ) ;
26- } else if ( ! Database . instance . initialized ) {
22+ } else if ( ! Database . instance . isLoaded ) {
2723 Database . instance . initialize ( workspacePath ) ;
2824 }
29-
30- if ( ! Database . instance . initialized ) {
31- throw new Error ( 'Database could not be initialized.' ) ;
32- }
33-
3425 return Database . instance ;
3526 }
3627
37- private async unzipIfNeeded ( line : string ) : Promise < string > {
28+ private unzipIfNeeded ( line : string ) : string | undefined {
3829 try {
3930 const buffer = Buffer . from ( line , 'base64' ) ;
4031 if ( buffer [ 0 ] === 0x1f && buffer [ 1 ] === 0x8b ) {
41- const decompressed = await this . gunzip ( buffer ) ;
42- return decompressed . toString ( 'utf-8' ) ;
32+ return zlib . gunzipSync ( buffer ) . toString ( 'utf-8' ) ;
4333 }
4434 return line ;
4535 } catch ( error ) {
36+ vscode . window . showErrorMessage ( `Error unzipping file: ${ error } ` ) ;
4637 throw new Error ( `Error unzipping file: ${ error } ` ) ;
4738 }
4839 }
4940
50- private async zip ( line : string ) : Promise < string > {
41+ private zip ( line : string ) : string {
5142 try {
52- const compressed = await this . gzip ( Buffer . from ( line , 'utf-8' ) ) ;
53- return compressed . toString ( 'base64' ) ;
43+ return zlib . gzipSync ( Buffer . from ( line , 'utf-8' ) ) . toString ( 'base64' ) ;
5444 } catch ( error ) {
45+ vscode . window . showErrorMessage ( `Error unzipping file: ${ error } ` ) ;
5546 throw new Error ( `Error zipping file: ${ error } ` ) ;
5647 }
5748 }
5849
59- private async initialize ( workspacePath : string ) : Promise < void > {
60- if ( this . initialized ) {
61- return ;
62- }
63-
64- if ( ! workspacePath ) {
65- this . initialized = false ;
66- throw new Error ( 'Workspace path is required to initialize the database.' ) ;
67- }
68-
50+ private initialize ( workspacePath : string ) {
6951 this . dbPath = path . join ( workspacePath , this . CONFIG_FILE_NAME ) ;
52+ this . db = new this . Datastore ( {
53+ filename : this . dbPath ,
54+ beforeDeserialization : ( line : string ) => this . unzipIfNeeded ( line ) ,
55+ afterSerialization : ( line : string ) => this . zip ( line )
56+ } ) ;
7057
7158 try {
72- this . db = new this . Datastore ( {
73- filename : this . dbPath ,
74- beforeDeserialization : async ( line : string ) => {
75- return await this . unzipIfNeeded ( line ) ;
76- } ,
77- afterSerialization : async ( line : string ) => {
78- return await this . zip ( line ) ;
79- }
80- } ) ;
81-
82- this . initialized = true ;
83- } catch ( error ) {
84- this . initialized = false ;
85- throw new Error ( `Error initializing database at ${ this . dbPath } : ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
86- }
87-
88- try {
89- await vscode . workspace . fs . stat ( vscode . Uri . file ( this . dbPath ) ) ;
59+ vscode . workspace . fs . stat ( vscode . Uri . file ( this . dbPath ) ) ;
9060 this . enableStorage ( ) ;
61+ this . isLoaded = true ;
9162 } catch {
92- console . log ( `Database file not found at ${ this . dbPath } .` ) ;
63+ this . isLoaded = false ;
9364 }
9465 }
9566
96- private async enableStorage ( ) : Promise < void > {
97- if ( ! this . initialized ) {
98- return ;
99- }
100-
101- await this . db . loadDatabaseAsync ( ) ;
102- await this . db . compactDatafileAsync ( ) ;
103-
67+ private enableStorage ( ) : void {
68+ this . db . loadDatabase ( ) ;
69+ this . db . persistence . compactDatafile ( ) ;
10470 this . db . persistence . setAutocompactionInterval ( 1000 * 60 * 10 ) ;
105-
106- this . isLoaded = true ;
10771 }
10872
10973 public isDatabaseLoaded ( ) : boolean {
11074 return this . isLoaded ;
11175 }
11276
113- public async getProjects ( ) : Promise < ( ProjectInfo & { results : Backtest [ ] } ) [ ] > {
114- return await this . db . findAsync ( { } ) ;
77+ public getProjects ( ) : ( ProjectInfo & { results : Backtest [ ] } ) [ ] {
78+ if ( ! this . isLoaded ) {
79+ return [ ] ;
80+ }
81+ return this . db . find ( { } ) ;
11582 }
11683
117- public async getProject ( projectId : string ) : Promise < ( ProjectInfo & { results : Backtest [ ] } ) | undefined > {
118- return await this . db . findOneAsync ( { _id : projectId } ) ;
84+ public getProject ( projectId : string ) : ( ProjectInfo & { results : Backtest [ ] } ) | undefined {
85+ return this . db . findOne ( { _id : projectId } ) ;
11986 }
12087
121- public async getProjectByName ( projectName : string ) : Promise < ( ProjectInfo & { results : Backtest [ ] } ) | undefined > {
122- return await this . db . findOneAsync ( { name : projectName } ) ;
88+ public getProjectByName ( projectName : string ) : ( ProjectInfo & { results : Backtest [ ] } ) | undefined {
89+ return this . db . findOne ( { name : projectName } ) ;
12390 }
12491
125- public async addProject ( projectData : ProjectInfo ) : Promise < ProjectInfo > {
126- await this . enableStorage ( ) ;
127-
92+ public addProject ( projectData : ProjectInfo ) : ProjectInfo {
93+ this . enableStorage ( ) ;
12894 const projectToInsert = {
129- ...projectData ,
130- results : projectData . results || [ ] , // Initialize if not present
131- lastConfig : projectData . lastConfig || { } , // Initialize if not present
132- created : projectData . created || new Date ( ) , // Set if not present
133- updated : projectData . updated || new Date ( ) , // Set if not present
95+ ...projectData ,
96+ results : projectData . results || [ ] ,
97+ lastConfig : projectData . lastConfig || { } ,
98+ created : projectData . created || new Date ( ) ,
99+ updated : projectData . updated || new Date ( ) ,
134100 } ;
135- const insertedProject = await this . db . insertAsync ( projectToInsert ) ;
136-
137- return insertedProject as ProjectInfo ; // Cast because NeDB types might be generic
101+ const insertedProject = this . db . insert ( projectToInsert ) ;
102+ return insertedProject as ProjectInfo ;
138103 }
139104
140- public async updateProject ( projectId : string , updates : Partial < ProjectInfo > ) : Promise < void > {
141- await this . db . updateAsync ( { _id : projectId } , { $set : updates } , { } ) ;
105+ public updateProject ( projectId : string , updates : Partial < ProjectInfo > ) : void {
106+ this . db . update ( { _id : projectId } , { $set : updates } , { } ) ;
142107 }
143108
144- public async updateLastConfig ( projectId : string , config : any ) : Promise < void > {
145- await this . db . updateAsync ( { _id : projectId } , { $set : { lastConfig : config } } , { } ) ;
109+ public updateLastConfig ( projectId : string , config : any ) : void {
110+ this . db . update ( { _id : projectId } , { $set : { lastConfig : config } } , { } ) ;
146111 }
147112
148- public async deleteProject ( projectId : string ) : Promise < void > {
149- const numRemoved = await this . db . removeAsync ( { _id : projectId } , { } ) ;
113+ public deleteProject ( projectId : string ) : void {
114+ const numRemoved = this . db . remove ( { _id : projectId } , { } ) ;
150115 if ( numRemoved === 0 ) {
151116 throw new Error ( `Project not found: ${ projectId } ` ) ;
152117 }
153118 }
154119
155- public async getBacktestResults ( projectId : string ) : Promise < Backtest [ ] > {
156- const project = await this . getProject ( projectId ) ;
120+ public getBacktestResults ( projectId : string ) : Backtest [ ] {
121+ const project = this . getProject ( projectId ) ;
157122 return project ?. results || [ ] ;
158123 }
159124
160- public async addBacktestResult ( projectId : string , result : Backtest ) : Promise < void > {
161- const numUpdated = await this . db . updateAsync (
125+ public addBacktestResult ( projectId : string , result : Backtest ) : void {
126+ const numUpdated = this . db . update (
162127 { _id : projectId } ,
163128 { $push : { results : result } } ,
164129 { }
@@ -168,8 +133,8 @@ export class Database {
168133 }
169134 }
170135
171- public async deleteBacktestResult ( projectId : string , resultId : string ) : Promise < void > {
172- const numUpdated = await this . db . updateAsync (
136+ public deleteBacktestResult ( projectId : string , resultId : string ) : void {
137+ const numUpdated = this . db . update (
173138 { _id : projectId } ,
174139 { $pull : { results : { id : resultId } } } ,
175140 { }
@@ -179,7 +144,7 @@ export class Database {
179144 }
180145 }
181146
182- public async saveDatabase ( ) : Promise < void > {
183- await this . db . persistence . compactDatafileAsync ( ) ;
147+ public saveDatabase ( ) : void {
148+ this . db . persistence . compactDatafile ( ) ;
184149 }
185150}
0 commit comments