[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