vscode里面SQLite数据库使用

上一篇文章提及到vscode里面涉及到两个数据库的使用,IndexDB和SQLite,关于IndexDB数据库的使用,感兴趣的同学可以查看我的上一篇文章,本文主要讲解SQLite数据库。

SQLite,著名的本地关系型数据库,官网: https://www.sqlite.org/index.html

vscode在此基础上进行了封装@vscode/sqlite3
npm: https://www.npmjs.com/package/@vscode/sqlite3
github: https://github.com/microsoft/vscode-node-sqlite3
文档:https://github.com/TryGhost/node-sqlite3/wiki/API#getsql–param—callback

npm install sqlite3
# or
yarn add sqlite3

使用,官方给了一个简单的例子:

const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');

db.serialize(() => {
    
    
    db.run("CREATE TABLE lorem (info TEXT)");

    const stmt = db.prepare("INSERT INTO lorem VALUES (?)");
    for (let i = 0; i < 10; i++) {
    
    
        stmt.run("Ipsum " + i);
    }
    stmt.finalize();

    db.each("SELECT rowid AS id, info FROM lorem", (err, row) => {
    
    
        console.log(row.id + ": " + row.info);
    });
});

db.close();

执行结果
在这里插入图片描述

封装一个简单是增删改查的例子

export interface IDatabaseNew {
    
    
	// getSome(): void;
	// getProjectInformationDB(): Promise<any>;
	deleteData(queryKey: string, queryValue: any): Promise<any>;
	insertData(data: object): Promise<boolean>;
	queryData(queryKey: string, queryValue: string): Promise<any>;
	updataData(queryMap: {
    
     [propName: string]: any }, conditions: {
    
     [propName: string]: any }): Promise<boolean>;
}


export class DatabaseNew implements IDatabaseNew {
    
    

	private readonly DB = this.connect(this.path, this.tableName);
	private readonly session = this.getSession();

	constructor(
		private readonly path: string,
		private readonly tableName: string,
		private readonly userAuthenticationService: IUserAuthenticationService,
	) {
    
    

	}

	async getSession() {
    
    
		return await this.userAuthenticationService.getSession();
	}

	async updataData(queryMap: {
    
     [propName: string]: any }, conditions: {
    
     [propName: string]: any }): Promise<boolean> {
    
    
		// db.serialize
		let DB = await this.DB;
		// let session = await this.session;
		return new Promise<boolean>((resolve, reject) => {
    
    
			if (queryMap && Object.keys(queryMap).length > 0) {
    
    
				DB.all(`PRAGMA table_info(${
      
      this.tableName})`, async (err: any, rows: any) => {
    
    
					if (err) {
    
    
						reject(false);
					}
					const keyNameList = rows.map((it: {
     
      name: any }) => it.name);
					const keyList: string[] = [];
					const valueList: any[] = [];
					for (let key of Object.keys(queryMap)) {
    
    
						let value = queryMap[key];
						keyList.push(key);
						if (keyNameList.indexOf(key) === -1) {
    
    
							DB = await new Promise<Database>((res, rej) => {
    
    
								const newdb = DB.run(`ALTER TABLE ${
      
      this.tableName} ADD COLUMN ${
      
      key} NONE`, (err: any) => {
    
    
									if (err) {
    
    
										rej(err);
									}
									res(newdb);
								});
							});
						}
						if (value instanceof Object) {
    
    
							valueList.push(JSON.stringify(value));
						} else {
    
    
							valueList.push(value);
						}
					}
					// eslint-disable-next-line code-no-unexternalized-strings
					DB.run(`UPDATE  ${
      
      this.tableName} SET ${
      
      keyList.map(item => item + '=?').join(',')} WHERE  ${
      
      Object.keys(conditions).map(item => item + '=?').join(',')} ;`, [...valueList, ...Object.values(conditions)], (err: any, row: any) => {
    
    
						if (err) {
    
    
							reject(false);
						}
						resolve(true);
					});
				});

			} else {
    
    
				reject(false);
			}

		});
	}

	async deleteData(queryKey: string, queryValue: any): Promise<any> {
    
    
		let DB = await this.DB;
		// let session = await this.session;
		return new Promise<any>((resolve, reject) => {
    
    
			DB.get(`DELETE FROM ${
      
      this.tableName} WHERE ${
      
      queryKey} = '${
      
      queryValue}' ;`, (err: any, row: any) => {
    
    
				if (err) {
    
    
					reject(err);
				}
				resolve(true);
			});
		});
	}

	async selecAllData(): Promise<any> {
    
    
		let DB = await this.DB;
		return new Promise<any>((resolve, reject) => {
    
    
			DB.all(`SELECT * FROM ${
      
      this.tableName} ;`, (err: any, row: any) => {
    
    
				if (err) {
    
    
					resolve(undefined);
				}
				if (row && row.length) {
    
    
					row.forEach((item: any) => {
    
    
						for (let key of Object.keys(item)) {
    
    
							let value = item[key];
							if (isJSON(value)) {
    
    
								item[key] = JSON.parse(value);
							}
						}
					});

				}
				resolve(row);
			});
		});
	}


	async queryData(queryKey: string, queryValue: any): Promise<any> {
    
    
		let DB = await this.DB;
		return new Promise<any>((resolve, reject) => {
    
    
			DB.get(`SELECT * FROM ${
      
      this.tableName} WHERE ${
      
      queryKey} = '${
      
      queryValue}' ;`, (err: any, row: any) => {
    
    
				if (err) {
    
    
					resolve(undefined);
				}
				if (row && Object.keys(row).length > 0) {
    
    
					for (let key of Object.keys(row)) {
    
    
						let value = row[key];
						if (isJSON(value)) {
    
    
							row[key] = JSON.parse(value);
						}
					}
				}
				resolve(row);
			});
		});
	}



	async insertData(data: {
    
     [propName: string]: any }): Promise<boolean> {
    
    
		let DB = await this.DB;
		return new Promise<boolean>((resolve, reject) => {
    
    
			DB.serialize(() => {
    
    
				DB.all(`PRAGMA table_info(${
      
      this.tableName})`, async (err: any, rows: any) => {
    
    
					if (err) {
    
    
						reject(false);
					}
					const keyNameList = rows.map((it: {
     
      name: any }) => it.name);
					if (data && Object.keys(data).length > 0) {
    
    
						const keyList: string[] = [];
						const valueList: any[] = [];

						for (let key of Object.keys(data)) {
    
    
							let value = data[key];
							keyList.push(key);
							if (keyNameList.indexOf(key) === -1) {
    
    
								DB = await new Promise<Database>((resolve, reject) => {
    
    
									const newdb = DB.run(`ALTER TABLE ${
      
      this.tableName} ADD COLUMN ${
      
      key} NONE`, (err: any) => {
    
    
										if (err) {
    
    
											reject(err);
										}
										resolve(newdb);
									});
								});

							}
							if (value instanceof Object) {
    
    
								valueList.push(JSON.stringify(value));
							} else {
    
    
								valueList.push(value);
							}
						}

						const stmt = DB.prepare(`INSERT INTO ${
      
      this.tableName} (${
      
      keyList.join(',')})  VALUES(${
      
      new Array(keyList.length).fill('?').join(',')})`);
						stmt.run(valueList);
						stmt.finalize();
						resolve(true);
					}
					reject(false);
				});
			});

		});
	}



	connect(path: string, tableName: string): Promise<Database> {
    
    
		return new Promise((resolve, reject) => {
    
    
			try {
    
    
				import('@vscode/sqlite3').then(sqlite3 => {
    
    
					const db: Database = new (sqlite3.Database)(path, error => {
    
    
						if (error) {
    
    
							return db ? db.close(() => reject(error)) : reject(error);
						}
						if (tableName) {
    
    
							db.exec(`CREATE TABLE IF NOT EXISTS ${
      
      tableName} (
								id INTEGER PRIMARY KEY
							  )`, (err: any) => {
    
    
								if (err) {
    
    
									db.close();
									return reject(err);
								}
							});
						}
					});
					resolve(db);
				});
			} catch (error) {
    
    
				if (error && error.code === 'SQLITE_BUSY') {
    
    
					return this.connect(path, tableName);
				}
				return reject(error);
			}

		});
	}
	async close(): Promise<void | null> {
    
    
		const DB = await this.DB;
		return new Promise((resolve, reject) => {
    
    
			DB.close((Error) => {
    
    
				if (Error) {
    
    
					reject(Error);
				}
				resolve();
			});
		});
	}
}

实现一个服务

export interface IDatabaseService {
    
    
	readonly _serviceBrand: undefined;
	// getSome(): void;
	getProjectInformationDB(): DatabaseNew;
	getDatabaseDB(path?: string, tableName?: string): Promise<any>;
}

export class DatabaseService extends Disposable implements IDatabaseService {
    
    
	declare readonly _serviceBrand: undefined;

	constructor(
		// @IContextKeyService private contextKeyService: IContextKeyService,
		// @IEditorService private editorService: IEditorService,
		@IUserAuthenticationService private readonly userAuthenticationService: IUserAuthenticationService,
		@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
	) {
    
    
		super();
	}

	getProjectInformationDB(): DatabaseNew {
    
    
		let path = resources.joinPath(this.environmentService.globalStorageHome, 'info.db').fsPath;
		return new DatabaseNew(path, 'projectInfo', this.userAuthenticationService);
	}

	getDatabaseDB(path?: string, tableName?: string) {
    
    
		return new Promise((resolve, reject) => {
    
    
			import('@vscode/sqlite3').then(sqlite3 => {
    
    
				const db: Database = new (sqlite3.Database)('text.db', error => {
    
    
					if (error) {
    
    
						return db ? db.close(() => reject(error)) : reject(error);
					}
					if (tableName) {
    
    
						db.exec(`CREATE TABLE IF NOT EXISTS ${
      
      tableName} (
							id INTEGER PRIMARY KEY
						  )`, (err: any) => {
    
    
							if (err) {
    
    
								return reject(err);
							}
						});
					}
				});
				resolve(db);
			});
		});
	}

}

调用

// 插件里根据pathId查询数据
CommandsRegistry.registerCommand('vscode.getdataFromDB', async (accessor: ServicesAccessor, ...args) => {
    
    
	const databaseService = accessor.get(IDatabaseService);
	const path = args[0];
	const dataBase = databaseService.getProjectInformationDB();
	const data = await dataBase.queryData('pathId', path);
	dataBase.close();
	return data;
});

CommandsRegistry.registerCommand('vscode.updatedataDB', async (accessor: ServicesAccessor, ...args) => {
    
    
	const databaseService = accessor.get(IDatabaseService);
	const path = args[0];
	const datas = args[1];
	const dataBase = databaseService.getProjectInformationDB();
	const data = await dataBase.queryData('pathId', path);
	if (data) {
    
    
		const reuslt = await dataBase.updataData(datas, {
    
     pathId: path });
		dataBase.close();
		return reuslt;
	} else {
    
    
		dataBase.close();
	}
	return null;
});

CommandsRegistry.registerCommand('vscode.insertdataDB', async (accessor: ServicesAccessor, ...args) => {
    
    
	const databaseService = accessor.get(IDatabaseService);
	const json = args[0];
	const dataBase = databaseService.getProjectInformationDB();
	const data = await dataBase.insertData(json);
	dataBase.close();
	if (data) {
    
    
		return true;
	} else {
    
    
		dataBase.close();
	}
	return null;
});

CommandsRegistry.registerCommand('vscode.deletedataDB', async (accessor: ServicesAccessor, ...args) => {
    
    
	const databaseService = accessor.get(IDatabaseService);
	const key = args[0];
	const value = args[1];
	const dataBase = databaseService.getProjectInformationDB();
	const data = await dataBase.deleteData(key, value);
	dataBase.close();
	if (data) {
    
    
		return true;
	} else {
    
    
		dataBase.close();
	}
	return null;
});

猜你喜欢

转载自blog.csdn.net/woyebuzhidao321/article/details/129636039