forked from niquola/plpl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7bb3241
Showing
15 changed files
with
360 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*sw? | ||
node_modules | ||
dist | ||
lib | ||
npm-debug.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
sample | ||
|
||
```sh | ||
nvm install 0.12 | ||
nvm use 0.12 | ||
npm install | ||
source config.sh && npm start | ||
``` | ||
## PLPL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env coffee | ||
path = require('path') | ||
fs = require('fs') | ||
lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib') | ||
require(lib + '/cli.js').run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "plpl", | ||
"description": "node + plv8 + pg", | ||
"version": "0.0.1", | ||
"dependencies": { | ||
"cli": "latest", | ||
"cli-table": "latest" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/niquola/plpl" | ||
}, | ||
"devDependencies": { | ||
"coffee": "latest", | ||
"jasmine-node": "latest", | ||
"pg-native":"latest" | ||
}, | ||
"author": "niquola", | ||
"engines": { "node": ">=0.10" }, | ||
"homepage": "https://github.com/niquola/plpl", | ||
"files": ["bin", "lib", "src"], | ||
"scripts": { | ||
"publish": "coffee -o lib/ -c src/ && npm publish", | ||
"watch": "webpack --progress --colors --watch", | ||
"build": "`npm bin`/coffee --output lib --compile src && ls lib -R", | ||
"test": "", | ||
"test-watch": "", | ||
"watch": "coffee -w --output lib --compile src" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export DATABASE_URL=postgres://localhost:5432/test | ||
export MIGRATIONS_DIR=./migrations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
exports.up = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') | ||
|
||
exports.down = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') |
7 changes: 7 additions & 0 deletions
7
sample/migrations/2015-07-14T21:25:10.834Z__create_users.coffee
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
exports.up = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') | ||
|
||
exports.down = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
plv8 = require('./src/plv8') | ||
loader = require('./src/loader') | ||
|
||
console.log plv8.execute 'select 1' | ||
|
||
loader.scan('./scratch_code.coffee') | ||
|
||
mod = require('./scratch_code.coffee') | ||
|
||
mod.generate_table(plv8, 'users') | ||
|
||
console.log plv8.execute 'select plv8_add(1, 3)' | ||
console.log plv8.execute 'select generate_table($1)', ['musers'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
plv8_add = (a, b)-> a + b | ||
|
||
module.exports.plv8_add = plv8_add | ||
plv8_add.plv8 = 'plv8_add(a int, b int) RETURNS int' | ||
|
||
generate_table = (plv8, nm)-> | ||
tbl = plv8.quote_ident(nm) | ||
plv8.execute """ | ||
DROP TABLE IF EXISTS #{tbl}; | ||
CREATE TABLE #{tbl} ( | ||
id serial PRIMARY KEY, | ||
data jsonb | ||
); | ||
""" | ||
plv8.elog(INFO, "table #{tbl} generated") | ||
"table #{tbl} generated" | ||
|
||
module.exports.generate_table = generate_table | ||
generate_table.plv8 = 'generate_table(nm text) RETURNS text' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
mig = require './migrations' | ||
load = require './loader' | ||
|
||
migrate = (args)-> | ||
mig.up() | ||
|
||
generate_migration = (args)-> | ||
mig.generate(args[0]) | ||
|
||
|
||
reload = (args)-> | ||
|
||
commands = | ||
reload: | ||
default: | ||
fn: reload | ||
args: '' | ||
desc: 'reload procedures' | ||
watch: | ||
fn: reload | ||
args: '' | ||
desc: 'watch src directory and update procs' | ||
migrate: | ||
default: | ||
fn: migrate | ||
args: '' | ||
desc: 'migrate up' | ||
new: | ||
fn: generate_migration | ||
args: '<migration_name>' | ||
desc: 'generate new migration' | ||
|
||
print_usage = (commands)-> | ||
for k,v of commands | ||
for sk, vv of v | ||
sk = '' if sk == 'default' | ||
console.log "\nplpl #{k} #{sk} #{vv.args}" | ||
console.log " #{vv.desc}" | ||
console.log "" | ||
|
||
exports.run = ()-> | ||
cmd_nm = process.argv[2] | ||
if not cmd_nm | ||
print_usage(commands) | ||
|
||
subcmd_nm = process.argv[3] || 'default' | ||
args = process.argv[4..-1] | ||
|
||
cmd = commands[cmd_nm] | ||
unless cmd | ||
console.log("Unknown command #{cmd_nm}") | ||
return | ||
subcmd = cmd[subcmd_nm] | ||
unless subcmd | ||
console.log("Unknown sub-command #{subcmd_nm}") | ||
return | ||
subcmd.fn(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
require('coffee-script/register') | ||
path = require('path') | ||
plv8 = require('./plv8') | ||
Module = require("module") | ||
|
||
currentModule = null | ||
modules_idx = {} | ||
plv8_exports = {} | ||
|
||
oldrequire = Module::require | ||
|
||
Module::require = (fl) -> | ||
currentModule = fl | ||
oldrequire.apply this, arguments | ||
|
||
oldcompile = Module::_compile | ||
|
||
Module::_compile = (answer, filename) -> | ||
modules_idx[currentModule] ={ filename: filename, code: answer} | ||
res = oldcompile.apply(this, arguments) | ||
for k,v of @exports when v.plv8? | ||
plv8_exports[k] ={fn: v, filename: filename} | ||
res | ||
|
||
_isAbsolute = (pth)-> | ||
path.resolve(pth) == path.normalize(pth) | ||
|
||
scan = (pth) -> | ||
unless _isAbsolute(pth) | ||
pth = path.normalize(path.join(path.dirname(module.parent.filename), pth)) | ||
|
||
currentModule = null | ||
Module._cache = {} | ||
modules_idx = {} | ||
plv8_exports = {} | ||
|
||
delete require.cache | ||
|
||
#TODO: calculate path from calling module | ||
file = require(pth) | ||
|
||
modules_js = generate_modules(modules_idx) | ||
plv8.execute "CREATE EXTENSION IF NOT EXISTS plv8" | ||
for k,v of plv8_exports | ||
sql = generate_plv8_fn(pth, k, modules_js, v.fn) | ||
console.log('-- Load ', v.fn.plv8) | ||
#console.log(sql) | ||
plv8.execute(sql) | ||
|
||
generate_modules = (modules_idx)-> | ||
mods = [] | ||
for m,v of modules_idx | ||
console.log("dep: #{m}") | ||
mods.push "deps['#{m}'] = function(module, exports, require){#{v.code}};" | ||
mods.join("\n") | ||
|
||
generate_plv8_fn = (mod, k, modules_js, fn)-> | ||
def_fn = fn.plv8 | ||
def_call = fn.toString().split("{")[0].split("function")[1].trim() | ||
|
||
""" | ||
CREATE OR REPLACE FUNCTION #{def_fn} AS $$ | ||
var deps = {} | ||
var cache = {} | ||
#{modules_js} | ||
var require = function(dep){ | ||
if(!cache[dep]) { | ||
var module = {exports: {}}; | ||
deps[dep](module, module.exports, require); | ||
cache[dep] = module.exports; | ||
} | ||
return cache[dep] | ||
} | ||
return require('#{mod}').#{k}#{def_call}; | ||
$$ LANGUAGE plv8 IMMUTABLE STRICT; | ||
""" | ||
exports.scan = scan |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
plv8 = require('./plv8') | ||
fs = require('fs') | ||
|
||
MIGRATION_REG = /^\d.*__.*/ | ||
parse_name = (x)-> | ||
parts = x.split('__') | ||
{ts: parts[0].replace(/_/g,' '), name: parts[1].split('.')[0]} | ||
|
||
ensure_migrations_table = ()-> | ||
unless plv8.execute("select to_regclass('public._migrations')")[0] | ||
plv8.execute """ | ||
create table if not exists _migrations ( | ||
name text PRIMARY KEY, | ||
ts timestamp | ||
) | ||
""" | ||
|
||
past_migrations = ()-> | ||
res = plv8.execute('SELECT * from _migrations') | ||
res.reduce ((a,x)-> a[x.name] = x; a), {} | ||
|
||
existing_migrations = (dir)-> | ||
files = fs.readdirSync(dir) | ||
for x in files.sort() when x.match(MIGRATION_REG) | ||
m = parse_name(x) | ||
m.file = "#{dir}/#{x}" | ||
m | ||
|
||
save_migration = (m)-> | ||
plv8.execute 'INSERT INTO _migrations (name, ts) VALUES ($1,$2)', [m.name, m.ts] | ||
|
||
rm_migration = (m)-> | ||
plv8.execute 'DELETE FROM _migrations WHERE name = $1', [m.name] | ||
|
||
clear_migrations = ()-> | ||
plv8.execute 'TRUNCATE _migrations' | ||
|
||
migrate_up = (m)-> | ||
mod = require(m.file) | ||
console.log("migrating #{m.ts} #{m.name}...") | ||
if mod.up | ||
mod.up(plv8) | ||
else | ||
throw new Error("No exports.up for #{m.file}") | ||
save_migration(m) | ||
|
||
migrate_down = (m)-> | ||
mod = require(m.file) | ||
console.log("rolling back #{m.ts} #{m.name}...") | ||
if mod.down | ||
mod.down(plv8) | ||
else | ||
throw new Error("No exports.down for #{m.file}") | ||
save_migration(m) | ||
|
||
pending = (dir)-> | ||
past = past_migrations() | ||
existing_migrations(dir).filter (x)-> | ||
not past[x.name] | ||
|
||
ensure_migrations_dir = (dir)-> | ||
dir = dir || process.env.MIGRATIONS_DIR | ||
unless dir | ||
throw new Error("Please export MIGRATIONS_DIR=???") | ||
dir | ||
|
||
up = (dir)-> | ||
dir = ensure_migrations_dir(dir) | ||
ensure_migrations_table() | ||
pnd = pending(dir) | ||
for m in pending(dir) | ||
migrate_up(m) | ||
if pnd.length == 0 | ||
console.log "No pending migrations" | ||
else | ||
console.log "All migrations done!" | ||
|
||
spit = (pth, cnt)-> | ||
fd = fs.openSync(pth, 'a') | ||
fs.writeSync(fd, cnt) | ||
fs.closeSync(fd) | ||
|
||
generate = (name, dir)-> | ||
unless name | ||
throw new Error('name is required') | ||
dir = ensure_migrations_dir(dir) | ||
nm = "#{(new Date()).toISOString()}__#{name}.coffee" | ||
spit "#{dir}/#{nm}", """ | ||
exports.up = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') | ||
exports.down = (plv8)-> | ||
# plv8.execute "" | ||
throw new Error('Not implemented') | ||
""" | ||
|
||
module.exports.up = up | ||
module.exports.generate = generate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
Client = require('pg-native') | ||
global.INFO="INFO" | ||
global.ERROR="ERROR" | ||
global.DEBUG="DEBUG" | ||
|
||
conn_string = process.env.DATABASE_URL | ||
|
||
unless conn_string | ||
throw new Error("set connection string \n export DATABASE_URL=postgres://user:password@localhost:5432/test") | ||
|
||
client = new Client | ||
client.connectSync(conn_string) | ||
module.exports = | ||
execute: -> | ||
client.querySync.apply(client, arguments).map (x) -> | ||
obj = {} | ||
for k of x | ||
if typeof x[k] == 'object' | ||
obj[k] = JSON.stringify(x[k]) | ||
else | ||
obj[k] = x[k] | ||
obj | ||
elog: (x, msg) -> | ||
console.log "#{x}:", msg | ||
return | ||
|
||
quote_literal: (str)-> str && client.pq.escapeLiteral(str) | ||
nullable: (str)-> | ||
quote_ident: (str)-> str && client.pq.escapeIdentifier(str) |