使用fs模块编写一个简单数据库(一)-nodejs
项目地址: github berryDB,npm berryDB,yarn berryDB
前些日子,给一部电脑配置mysql时,深感痛苦,深思一段时间后,我痛下决心,要写一个属于自己的数据库。
额。。。这名字可以些什么呢?我一扫桌上的酸梅汤,决定了,就叫"berry-database"吧。
由于是自娱自乐,所以可以简单实现下。
将一个文件夹当成数据库,表为文件。
经过深思,这款数据库与平常数据库不同,它目前有三种存储类型,表,数组与便签。
然后开始快乐的实现。
为了能让用户快乐地使用这个数据库,所以我决定了,开始从创建数据库的命令行开始。
首先,为了能与用户交互,所以可以首先编写一个工具,名字就叫berry-tool吧。为了能更方便地编写,我们先下载一个npm包:yargs($:npm install yargs
)。
为了能愉快使用,首先编写package.json文件。直接上代码:
{
"name": "berry-tool",
"version": "1.2.2",
"description": "This is a command line tool of berryDB.",
"main": "berry.js",
"directories": {
"doc": "doc"
},
"scripts": {
"test": "berry"
},
"keywords": [
"berry"
],
"bin": {
"berry": "./bin/berry.js"
},
"author": "yhzheng",
"license": "ISC",
"dependencies": {
"yargs": "^12.0.1"
}
}
在此之后,根据json文件的内容,我们创建一个bin文件夹,并创建berry.js。
因为这个数据库是简单通过fs模块进行读写操作,所以不仅需引入yargs模块,同时需引入fs模块。
然后可以确定一下该工具的内容,如下:
--create(-c) db xxx [创建数据库]
--create(-c) tab xxx [创建数据表]
--create(-c) arr xxx [创建数组]
--create(-c) nt xxx [创建便签]
--db(-d) xxx [在xx数据库]
--init(-i) xxx [初始化数据表]
--value(-v) xx,xx [初始化数据表时所需的属性]
--password(-p) xx,xx [数据库的密码]
并编写该文件开头:
#!/usr/bin/env node
var fs = require("fs");
var yargs = require('yargs');
/*
* params:
* --create(-c) db xxx [create db]
* --create(-c) tab xxx [create tab]
* --create(-c) arr xxx [create arr]
* --create(-c) nt xxx [create nt]
* --db(-d) xxx [in xx db]
* --init(-i) xxx [init tab]
* --value(-v) xx,xx [the value of tab]
* --password(-p) xx,xx [the password of db]
*/
yargs.alias('c', 'create');
yargs.alias('db', 'd');
yargs.alias('init', 'i');
yargs.alias('value', 'v');
yargs.alias('password', 'p');
var argv = yargs.argv;
由于创建数据库、数据表等文件是重中之重,所以,可以首先编写-c的内容。
查看上面,需创建的文件多种多样,使用switch语句为佳。
首先判断,如果是需创建数据库,可使用fs模块的fs.mkdirSync方法。
fs.mkdirSync(argv._[0]);
并且最好加入提示语以及防止用户输入的判断:
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This database don't have name.\033[0m");
} else {
if (fs.existsSync(argv._[0])){
console.log("\033[0;31m-ERR:Can't create this database.\033[0m");
} else {
fs.mkdirSync(argv._[0]);
console.log("\033[0;32mCreate success\033[0m");
}
}
接下来的模块可以使用fs.writeFileSync方法创建。接下来的方法我不赘述,可以自己思考,代码如下:
switch (argv.c){
case "db":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This database don't have name.\033[0m");
} else {
if (fs.existsSync(argv._[0])){
console.log("\033[0;31m-ERR:Can't create this database.\033[0m");
} else {
fs.mkdirSync(argv._[0]);
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "tab":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This table of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".tab","");
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "arr":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This array of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".arr","");
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "nt":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This note of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".nt","This is a note of " + argv.d + ".\nCreate Time:" + new Date().toUTCString());
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
default:
console.log("\033[0;31m-ERR:Don't have this type.\033[0m");
break;
}
为了方便起见,我们的数据表可以使用json对象存储,所以,--init方法也可以迎刃而解,使用JSON.stringify将一个对象转字符串。
if (argv.i !== undefined){
var table = {
"info": {},
"datas": {}
};
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
}
var types = argv.v.split(",");
for (var i in types){
table["info"][types[i]] = null;
}
fs.writeFileSync(argv.d + "/" + argv.i + ".tab",JSON.stringify(table));
}
最后存储密码则更简单了,可以直接将密码存储在一个文件中:
if (argv.p !== undefined){
fs.writeFileSync(argv.d + "/password.pw",argv.p);
console.log("\033[0;32mSet password success\033[0m");
}
现在,整个命令行工具就编写完了,所有代码如下:
#!/usr/bin/env node
var fs = require("fs");
var yargs = require('yargs');
/*
* params:
* --create(-c) db xxx [create db]
* --create(-c) tab xxx [create tab]
* --create(-c) arr xxx [create arr]
* --create(-c) nt xxx [create nt]
* --db(-d) xxx [in xx db]
* --init(-i) xxx [init tab]
* --value(-v) xx,xx [the value of tab]
* --password(-p) xx,xx [the password of db]
*/
yargs.alias('c', 'create');
yargs.alias('db', 'd');
yargs.alias('init', 'i');
yargs.alias('value', 'v');
yargs.alias('password', 'p');
var argv = yargs.argv;
switch (argv.c){
case "db":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This database don't have name.\033[0m");
} else {
if (fs.existsSync(argv._[0])){
console.log("\033[0;31m-ERR:Can't create this database.\033[0m");
} else {
fs.mkdirSync(argv._[0]);
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "tab":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This table of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".tab","");
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "arr":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This array of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".arr","");
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
case "nt":
if (argv._[0] === undefined){
console.log("\033[0;31m-ERR:This note of database don't have name.\033[0m");
} else {
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
} else {
fs.writeFileSync(argv.d + "/" + argv._[0] + ".nt","This is a note of " + argv.d + ".\nCreate Time:" + new Date().toUTCString());
console.log("\033[0;32mCreate success\033[0m");
}
}
break;
default:
console.log("\033[0;31m-ERR:Don't have this type.\033[0m");
break;
}
if (argv.i !== undefined){
var table = {
"info": {},
"datas": {}
};
if (argv.d === undefined){
console.log("\033[0;31m-ERR:The database don't have name.\033[0m");
}
var types = argv.v.split(",");
for (var i in types){
table["info"][types[i]] = null;
}
fs.writeFileSync(argv.d + "/" + argv.i + ".tab",JSON.stringify(table));
console.log("\033[0;32mInit success\033[0m");
}
if (argv.p !== undefined){
fs.writeFileSync(argv.d + "/password.pw",argv.p);
console.log("\033[0;32mSet password success\033[0m");
}
最后,还有很重要的一步,要将该文件以及所需的npm包也拷贝至bin文件夹才可使用。
一切准备就绪,开始发布至npm与yarn上,并进入下一个环节。
$:npm publish
$:yarn publish
第一部分[完]
共同学习,写下你的评论
评论加载中...
作者其他优质文章