Skip to content

Commit 532011c

Browse files
committed
Add a simple command line tool to manage modules in the DB
Working implementation with overridable config
1 parent c594740 commit 532011c

4 files changed

Lines changed: 175 additions & 37 deletions

File tree

index.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*eslint no-console: 0 */
2+
const config = require('npm-package-config').list();
23
const bootstrapPlv8 = require('./lib/bootstrap')
34
const babel = require('babel-core')
45
const browserify = require('browserify')
@@ -55,13 +56,13 @@ module.exports = class PLV8 {
5556
})
5657
})
5758
.then(code => {
58-
return this.knex('v8.modules').select('*').where({ name: moduleName })
59+
return this.knex(config.pg_modules_table).select('*').where({ name: moduleName })
5960
.then(result => {
6061
if (result.length > 0) {
61-
return this.knex('v8.modules').update({ code }).where({ name: moduleName })
62+
return this.knex(config.pg_modules_table).update({ code }).where({ name: moduleName })
6263
}
6364
else {
64-
return this.knex('v8.modules').insert({ code, name: moduleName })
65+
return this.knex(config.pg_modules_table).insert({ code, name: moduleName })
6566
}
6667
})
6768
})
@@ -70,7 +71,7 @@ module.exports = class PLV8 {
7071

7172
uninstall (moduleId) {
7273
const name = moduleId.replace(/^@\w+\//, '')
73-
return this.knex('v8.modules').where({ name }).del()
74+
return this.knex(config.pg_modules_table).where({ name }).del()
7475
.then(() => true)
7576
}
7677

@@ -120,7 +121,7 @@ module.exports = class PLV8 {
120121
}
121122
const code = es5.code.slice(0, -1)
122123

123-
return this.knex.raw('select v8.eval(?) as val', [ `${code}()` ])
124+
return this.knex.raw(`select ${config.pg_schema}.eval(?) as val`, [ `${code}()` ])
124125
.then(({ rows: [ result ] }) => {
125126
const val = result && result.val
126127
if (val && val.error === true) {
@@ -135,13 +136,13 @@ module.exports = class PLV8 {
135136
}
136137

137138
init () {
138-
return this.knex('pg_catalog.pg_namespace').select().where({ nspname: 'v8' })
139-
.then(([ schema ]) => {
140-
if (schema) {
139+
return this.knex('pg_catalog.pg_namespace').select(this.knex.raw(true)).where({ nspname: config.pg_schema })
140+
.then(([ exists ]) => {
141+
if (exists) {
141142
return
142143
}
143144
else {
144-
return this.knex.raw('create schema if not exists "v8"')
145+
return this.knex.raw(`create schema if not exists "${config.pg_schema}"`)
145146
}
146147
})
147148
.then(() => {
@@ -156,7 +157,7 @@ module.exports = class PLV8 {
156157
})
157158
})
158159
.then(() => {
159-
return this.knex.schema.createTableIfNotExists('v8.modules', table => {
160+
return this.knex.schema.createTableIfNotExists(config.pg_modules_table, table => {
160161
table.increments()
161162
table.text('name')
162163
table.text('code')

lib/bootstrap.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const evalOptions = {
99
ast: false,
1010
babelrc: false
1111
}
12+
const config = require('npm-package-config').list();
1213

1314
function plv8_init () {
1415
return `
@@ -34,15 +35,15 @@ function plv8_log (level, message) {
3435
function plv8_emit (event, payload) {
3536
try {
3637
payload = JSON.stringify(payload)
37-
plv8.execute('notify ' + event + ', \'' + payload + '\'')
38+
plv8.execute(`notify ${event}, '${payload}'`)
3839
}
3940
catch (e) {
40-
plv8.execute('notify ' + event)
41+
plv8.execute(`notify ${event}`)
4142
}
4243
}
4344

4445
function xpressionToBody(code){
45-
return '(' + code + ')'
46+
return `(${code})`
4647
}
4748

4849
module.exports = function(knex) {
@@ -53,44 +54,44 @@ module.exports = function(knex) {
5354
EXCEPTION WHEN OTHERS THEN END;
5455
$$;`.replace(/\n/g, ''))
5556
.then(() => {
56-
return knex.raw(`SET plv8.start_proc = 'v8.plv8_init';`)
57+
return knex.raw(`SET plv8.start_proc = '${config.pg_schema}.plv8_init';`)
5758
})
5859
.then(() => {
5960
return knex.raw(`
6061
DO $$ BEGIN
61-
CREATE DOMAIN v8.json AS json;
62+
CREATE DOMAIN ${config.pg_schema}.json AS json;
6263
EXCEPTION WHEN OTHERS THEN END;
6364
$$;`.replace(/\n/g, ''))
6465
})
6566
.then(() => {
66-
return knex.raw(createStoredProcedure('v8.plv8_init', { }, 'void', plv8_init(), true))
67+
return knex.raw(createStoredProcedure(`${config.pg_schema}.plv8_init`, { }, 'void', plv8_init(), true))
6768
})
6869
.then(() => {
6970
return Promise.all([
70-
knex.raw(createStoredProcedure('v8.eval', {
71+
knex.raw(createStoredProcedure(`${config.pg_schema}.eval`, {
7172
str: 'text'
72-
}, 'v8.json', plv8_eval)),
73-
knex.raw(createStoredProcedure('v8.apply', {
73+
}, `${config.pg_schema}.json`, plv8_eval)),
74+
knex.raw(createStoredProcedure(`${config.pg_schema}.apply`, {
7475
str: 'text',
75-
args: 'v8.json'
76-
}, 'v8.json', plv8_apply)),
77-
knex.raw(createStoredProcedure('v8.json_eval', {
76+
args: `${config.pg_schema}.json`
77+
}, `${config.pg_schema}.json`, plv8_apply)),
78+
knex.raw(createStoredProcedure(`${config.pg_schema}.json_eval`, {
7879
code: 'text'
79-
}, 'v8.json', wrapStoredProcedure(0), {
80+
}, `${config.pg_schema}.json`, wrapStoredProcedure(0), {
8081
cascade: true,
8182
boot: true
8283
})),
83-
knex.raw(createStoredProcedure('v8.json_eval', {
84-
data: 'v8.json',
84+
knex.raw(createStoredProcedure(`${config.pg_schema}.json_eval`, {
85+
data: `${config.pg_schema}.json`,
8586
code: 'text'
86-
}, 'v8.json', wrapStoredProcedure(-1), {
87+
}, `${config.pg_schema}.json`, wrapStoredProcedure(-1), {
8788
cascade: true,
8889
boot: true
8990
})),
90-
knex.raw(createStoredProcedure('v8.json_eval', {
91+
knex.raw(createStoredProcedure(`${config.pg_schema}.json_eval`, {
9192
code: 'text',
92-
data: 'v8.json'
93-
}, 'v8.json', wrapStoredProcedure(1), {
93+
data: `${config.pg_schema}.json`
94+
}, `${config.pg_schema}.json`, wrapStoredProcedure(1), {
9495
cascade: true,
9596
boot: true
9697
}))
@@ -101,16 +102,17 @@ function plv8_eval (str) {
101102
return eval(str)
102103
}
103104
function plv8_apply (func, args){
104-
func = '(function() {return (' + func + ');})()'
105+
func = `(function() {return (${func});})()`
105106
return eval(func).apply(null, args)
106107
}
107108

108109
function plv8_require (name) {
109-
var module = plv8.execute('select name, code from v8.modules where name = $1', [ name ])[0];
110+
var module = plv8.execute('select name, code from ${config.pg_modules_table} where name = $1', [ name ])[0];
110111

111112
if (!module) {
112-
plv8.elog(WARNING, 'Cannot find module \'' + name + '\'');
113-
return new Error('Cannot find module \'' + name + '\'');
113+
let msg = `Cannot find module '${name}`
114+
plv8.elog(WARNING, msg);
115+
return new Error(msg);
114116
}
115117

116118
require.cache[name] = eval(module.code)
@@ -137,7 +139,7 @@ function wrapStoredProcedure (type = 1) {
137139
function createStoredProcedure (name, paramObj, ret, func, init) {
138140
const signature = _.map(paramObj, (type, key) => {
139141
return {
140-
arg: (type === 'v8.json') ? `JSON.parse('${key}')` : key,
142+
arg: (type === `${config.pg_schema}.json`) ? `JSON.parse('${key}')` : key,
141143
param: `${key} ${type}`
142144
}
143145
})
@@ -148,11 +150,11 @@ function createStoredProcedure (name, paramObj, ret, func, init) {
148150

149151
let statement = `(${code})(${args})`
150152

151-
if (ret === 'v8.json') {
153+
if (ret === `${config.pg_schema}.json`) {
152154
statement = `JSON.stringify(${statement})`
153155
}
154156

155-
let initStatement = 'plv8.execute("select v8.plv8_init()");'
157+
let initStatement = `plv8.execute("select ${config.pg_schema}.plv8_init()");`
156158
if (init) {
157159
initStatement = ''
158160
}

lib/cli.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env node
2+
3+
'use strict';
4+
5+
const config = require('npm-package-config').list();
6+
7+
const program = require('commander')
8+
9+
program
10+
.version('1.0.0')
11+
12+
program
13+
.command('install <modules...>')
14+
.description('install one or more packages into the DB')
15+
.alias('i')
16+
.action((modules, options) => install(modules,options))
17+
18+
program
19+
.command('uninstall <module...>')
20+
.description('uninstall one or more packages from the DB')
21+
.alias('u')
22+
.action((modules, options) => uninstall(modules,options))
23+
24+
program
25+
.command('list')
26+
.description('list the packages currently installed in the DB')
27+
.alias('l')
28+
.action((options) => list(options))
29+
30+
program
31+
.on('--help', () => console.log(`
32+
Environment Configuration Options
33+
(Set with npm config or in your package.json)
34+
35+
pg_user: The name of the PostgreSQL user with which to authenticate -- default "postgres"; current "${config.pg_user}"
36+
pg_pass: The password of the PostgreSQL user with which to authenticate -- default "postgres"; current "****"
37+
pg_host: The name of the PostgreSQL server with which to connect -- default "localhost"; current "${config.pg_host}"
38+
pg_port: The port number of the PostgreSQL server -- default 5432; current "${config.pg_port}"
39+
pg_database: The database with which to interact -- default "postgres"; current "${config.pg_database}"
40+
pg_schema: the name of the schema in which to store modules -- default "v8"; current "${config.pg_schema}"
41+
pg_modules_table: The name of the table in which to store modules -- default "modules"; current "${config.pg_modules_table}"
42+
`)
43+
)
44+
45+
program.parse(process.argv)
46+
47+
function init(options) {
48+
const PLV8 = require('..'),
49+
knex = require('knex'),
50+
plv8 = new PLV8(knex({
51+
client: 'pg',
52+
connection: {
53+
host: config.pg_host,
54+
port: config.pg_port,
55+
database: config.pg_database,
56+
user: config.pg_user,
57+
password: config.pg_pass
58+
}
59+
}))
60+
return plv8
61+
}
62+
63+
64+
function list(options) {
65+
const plv8 = init(options)
66+
console.log('Currently installed modules:')
67+
plv8.knex
68+
.select('name')
69+
.from(`${config.pg_schema}.modules`)
70+
.then(result => {
71+
result.forEach(row => console.log(row.name));
72+
})
73+
.then(() => plv8.knex.destroy() )
74+
.catch(err => {
75+
console.log(""+err)
76+
process.exit(1)
77+
})
78+
}
79+
80+
function uninstall(modules, options) {
81+
const plv8 = init(options)
82+
modules.forEach(name => {
83+
plv8.knex(`${config.pg_schema}.${config.pg_modules_table}`)
84+
.where({name})
85+
.del()
86+
.returning({name})
87+
.then(result => console.log(`${result} removed`) )
88+
.then(() => plv8.knex.destroy() )
89+
.catch(err => {
90+
console.log(""+err)
91+
process.exit(1)
92+
})
93+
})
94+
}
95+
96+
function install(modules, options) {
97+
if (!modules.length) {
98+
console.error('One or more package arguments required.')
99+
process.exit(1)
100+
}
101+
102+
const plv8 = init(options)
103+
let moduleInstalls = modules.reduce((promiseChain, item) => {
104+
return promiseChain.then(() => new Promise((resolve) => {
105+
plv8
106+
.install({
107+
modulePath: require.resolve(item),
108+
moduleName: item
109+
})
110+
.then(moduleName => {
111+
console.log(`module ${moduleName} installed`)
112+
resolve()
113+
})
114+
.catch(err => {
115+
console.log(""+err)
116+
process.exit(1)
117+
})
118+
}))
119+
}, Promise.resolve())
120+
121+
122+
moduleInstalls
123+
.then(() => plv8.knex.destroy() )
124+
}

package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"require"
1313
],
1414
"main": "index.js",
15+
"bin": "./lib/cli.js",
1516
"repository": {
1617
"type": "git",
1718
"url": "git://github.com/langateam/plv8.git"
@@ -27,6 +28,14 @@
2728
"email": "tjwebb@langa.io"
2829
}
2930
],
31+
"config": {
32+
"pg_schema": "v8",
33+
"pg_modules_table": "modules",
34+
"pg_user": "postgres",
35+
"pg_host": "localhost",
36+
"pg_port": 5432,
37+
"pg_database": "postgres"
38+
},
3039
"scripts": {
3140
"test": "mocha"
3241
},
@@ -40,7 +49,9 @@
4049
"babel-preset-es2015": "^6.9.0",
4150
"babelify": "^7.3.0",
4251
"browserify": "^13.1.0",
43-
"lodash": "^4.13.1"
52+
"commander": "^2.9.0",
53+
"lodash": "^4.13.1",
54+
"npm-package-config": "^0.2.0"
4455
},
4556
"devDependencies": {
4657
"babel-preset-es2015": "^6.9.0",

0 commit comments

Comments
 (0)