[feat] first commit
This commit is contained in:
commit
fe42e9680c
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
5
Dockerfile
Normal file
5
Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM node:lts-slim
|
||||
WORKDIR /data
|
||||
COPY . .
|
||||
RUN npm install --prod
|
||||
|
154
index.js
Normal file
154
index.js
Normal file
@ -0,0 +1,154 @@
|
||||
const Redis = require('ioredis')
|
||||
const commander = require('commander')
|
||||
const fs = require('fs')
|
||||
const yaml = require('yaml')
|
||||
|
||||
function isNumeric (v) {
|
||||
return isFinite(v) && v !== null && v !== false && v !== true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} obj
|
||||
* @param {string[]} keys
|
||||
* @param {any} value
|
||||
*/
|
||||
function setKey (obj, keys, value) {
|
||||
const key = isNumeric(keys[0]) ? parseInt(keys[0], 10) : keys[0]
|
||||
|
||||
if (keys.length === 1) {
|
||||
obj[key] = value
|
||||
return
|
||||
}
|
||||
|
||||
if (!(key in obj)) {
|
||||
if (isNumeric(keys[1])) {
|
||||
obj[key] = []
|
||||
} else {
|
||||
obj[key] = {}
|
||||
}
|
||||
}
|
||||
|
||||
setKey(obj[key], keys.slice(1), value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @return {boolean}
|
||||
*/
|
||||
async function checkFileExists (file) {
|
||||
if (!file) return false
|
||||
|
||||
try {
|
||||
await fs.promises.access(file, fs.constants.W_OK || fs.constants.R_OK)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function getRedis () {
|
||||
const { port, host } = commander
|
||||
|
||||
const redis = new Redis(port || 6379, host || 'localhost')
|
||||
return redis
|
||||
}
|
||||
|
||||
function generateFromStruct (obj, prefix = '') {
|
||||
const kvs = []
|
||||
if (Object.keys(obj).length === 0) return kvs
|
||||
|
||||
for (const k in obj) {
|
||||
const key = !prefix ? k : [prefix, k].join('/')
|
||||
|
||||
if (typeof obj[k] === 'object') {
|
||||
kvs.push(...generateFromStruct(obj[k], key))
|
||||
} else {
|
||||
kvs.push({ key, value: `${obj[k]}` })
|
||||
}
|
||||
}
|
||||
|
||||
return kvs
|
||||
}
|
||||
|
||||
async function importData () {
|
||||
const { file } = commander
|
||||
if (!await checkFileExists(file)) throw new Error(`check file (${file}) fail`)
|
||||
const redis = getRedis()
|
||||
|
||||
const str = await fs.promises.readFile(file, 'utf8')
|
||||
const obj = yaml.parse(str)
|
||||
|
||||
const kvs = generateFromStruct(obj)
|
||||
|
||||
try {
|
||||
// clean redis
|
||||
await redis.flushdb()
|
||||
for (const o of kvs) {
|
||||
console.log(`set: ${o.key} => ${o.value}`)
|
||||
await redis.set(o.key, o.value)
|
||||
}
|
||||
} finally {
|
||||
await redis.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
async function exportData () {
|
||||
const { file } = commander
|
||||
const redis = getRedis()
|
||||
|
||||
const obj = {}
|
||||
|
||||
try {
|
||||
let cursor = ''
|
||||
while (cursor !== '0') {
|
||||
const result = await redis.scan(cursor || '0')
|
||||
|
||||
console.log(result)
|
||||
cursor = result[0]
|
||||
|
||||
for (const k of result[1]) {
|
||||
const str = await redis.get(k)
|
||||
if (!str) continue
|
||||
setKey(obj, k.split('/'), str)
|
||||
}
|
||||
}
|
||||
|
||||
await fs.promises.writeFile(file, yaml.stringify(obj))
|
||||
} finally {
|
||||
await redis.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
commander.option('-r, --run <module>', 'run tool module [import, export]')
|
||||
.option('-p, --port [port]', 'redis server port default: 6379')
|
||||
.option('-h, --host [host]', 'redis host addr default: localhost')
|
||||
.option('-f, --file <file path>', 'yaml config path')
|
||||
.parse(process.argv)
|
||||
|
||||
; (async () => {
|
||||
const { run, port, host, file } = commander
|
||||
|
||||
console.log(run, port, host, file)
|
||||
|
||||
switch (run) {
|
||||
case 'import':
|
||||
await importData()
|
||||
break
|
||||
case 'export':
|
||||
await exportData()
|
||||
break
|
||||
default:
|
||||
throw new Error('run module not support')
|
||||
}
|
||||
|
||||
// for (const key in json) {
|
||||
// const strs = key.split('/')
|
||||
// setKey(obj, strs, json[key])
|
||||
// }
|
||||
|
||||
// // console.log(yaml.stringify(obj))
|
||||
|
||||
// await fs.promises.writeFile('store.yml', yaml.stringify(obj))
|
||||
})().then(console.log).catch(console.log)
|
1973
package-lock.json
generated
Normal file
1973
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "aa",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"commander": "^6.2.0",
|
||||
"ioredis": "^4.19.2",
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^16.0.3"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user