waxx 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +201 -0
- data/README.md +879 -0
- data/bin/waxx +120 -0
- data/lib/waxx/app.rb +173 -0
- data/lib/waxx/conf.rb +54 -0
- data/lib/waxx/console.rb +204 -0
- data/lib/waxx/csrf.rb +14 -0
- data/lib/waxx/database.rb +80 -0
- data/lib/waxx/encrypt.rb +38 -0
- data/lib/waxx/error.rb +60 -0
- data/lib/waxx/html.rb +33 -0
- data/lib/waxx/http.rb +268 -0
- data/lib/waxx/init.rb +273 -0
- data/lib/waxx/irb.rb +44 -0
- data/lib/waxx/irb_env.rb +18 -0
- data/lib/waxx/json.rb +23 -0
- data/lib/waxx/mongodb.rb +221 -0
- data/lib/waxx/mysql2.rb +234 -0
- data/lib/waxx/object.rb +115 -0
- data/lib/waxx/patch.rb +138 -0
- data/lib/waxx/pdf.rb +69 -0
- data/lib/waxx/pg.rb +246 -0
- data/lib/waxx/process.rb +270 -0
- data/lib/waxx/req.rb +116 -0
- data/lib/waxx/res.rb +98 -0
- data/lib/waxx/server.rb +304 -0
- data/lib/waxx/sqlite3.rb +237 -0
- data/lib/waxx/supervisor.rb +47 -0
- data/lib/waxx/test.rb +162 -0
- data/lib/waxx/util.rb +57 -0
- data/lib/waxx/version.rb +3 -0
- data/lib/waxx/view.rb +389 -0
- data/lib/waxx/waxx.rb +73 -0
- data/lib/waxx/x.rb +103 -0
- data/lib/waxx.rb +50 -0
- data/skel/README.md +11 -0
- data/skel/app/app/app.rb +39 -0
- data/skel/app/app/error/app_error.rb +16 -0
- data/skel/app/app/error/dhtml.rb +9 -0
- data/skel/app/app/error/html.rb +8 -0
- data/skel/app/app/error/json.rb +8 -0
- data/skel/app/app/error/pdf.rb +13 -0
- data/skel/app/app/log/app_log.rb +13 -0
- data/skel/app/app.rb +20 -0
- data/skel/app/home/home.rb +16 -0
- data/skel/app/home/html.rb +145 -0
- data/skel/app/html.rb +192 -0
- data/skel/app/usr/email.rb +66 -0
- data/skel/app/usr/html.rb +115 -0
- data/skel/app/usr/list.rb +51 -0
- data/skel/app/usr/password.rb +54 -0
- data/skel/app/usr/record.rb +98 -0
- data/skel/app/usr/usr.js +67 -0
- data/skel/app/usr/usr.rb +277 -0
- data/skel/app/waxx/waxx.rb +109 -0
- data/skel/bin/README.md +1 -0
- data/skel/db/README.md +11 -0
- data/skel/db/app/0-init.sql +88 -0
- data/skel/lib/README.md +1 -0
- data/skel/log/README.md +1 -0
- data/skel/opt/dev/config.yaml +1 -0
- data/skel/opt/prod/config.yaml +1 -0
- data/skel/opt/stage/config.yaml +1 -0
- data/skel/opt/test/config.yaml +1 -0
- data/skel/private/README.md +1 -0
- data/skel/public/lib/site.css +202 -0
- data/skel/public/lib/waxx/w.ico +0 -0
- data/skel/public/lib/waxx/w.png +0 -0
- data/skel/public/lib/waxx/waxx.js +111 -0
- data/skel/tmp/pids/README.md +1 -0
- data.tar.gz.sig +0 -0
- metadata +140 -0
- metadata.gz.sig +3 -0
data/lib/waxx/patch.rb
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
|
|
2
|
+
# Released under the Apache Version 2 License. See LICENSE.txt.
|
|
3
|
+
|
|
4
|
+
# Patches to Ruby Classes
|
|
5
|
+
class Date
|
|
6
|
+
# HTML format for a date
|
|
7
|
+
def h
|
|
8
|
+
to_s.h
|
|
9
|
+
end
|
|
10
|
+
# Shortcut to format a date in strftime
|
|
11
|
+
def f(format='%d-%b-%Y')
|
|
12
|
+
strftime format
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
class FalseClass
|
|
16
|
+
# HTML format "false"
|
|
17
|
+
def h
|
|
18
|
+
"false"
|
|
19
|
+
end
|
|
20
|
+
# Format to a selected format (see TrueClass also)
|
|
21
|
+
# Format Options:
|
|
22
|
+
# yn: No
|
|
23
|
+
# tf: False
|
|
24
|
+
# icon: glyphicon (Bootstrap)
|
|
25
|
+
# num: 0
|
|
26
|
+
def f(format=:yn)
|
|
27
|
+
case format.to_sym
|
|
28
|
+
when :yn
|
|
29
|
+
"No"
|
|
30
|
+
when :tf
|
|
31
|
+
"False"
|
|
32
|
+
when :icon
|
|
33
|
+
'<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>'
|
|
34
|
+
when :num
|
|
35
|
+
"0"
|
|
36
|
+
else
|
|
37
|
+
raise "Unknown format in FalseClass.f: #{format}. Needs to be :yn, :tf, :icon, or :num."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
# Show false as zero
|
|
41
|
+
def to_i
|
|
42
|
+
0
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
class Hash
|
|
46
|
+
# Add an symbol/string indifferent access to a hash
|
|
47
|
+
def /(k)
|
|
48
|
+
self[k.to_sym] || self[k.to_s]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
class NilClass
|
|
52
|
+
# HTML format
|
|
53
|
+
def h
|
|
54
|
+
""
|
|
55
|
+
end
|
|
56
|
+
# Format nil as and empty string (2nd param)
|
|
57
|
+
# This is mostly for nil values out of the database
|
|
58
|
+
# that have a format f() called on them.
|
|
59
|
+
def f(size=2, zero_as="", t=",", d=".")
|
|
60
|
+
zero_as
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Convert a nil to an empty symbol
|
|
64
|
+
def to_sym
|
|
65
|
+
"".to_sym
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
class Numeric
|
|
69
|
+
# HTML format (self -- no escaping needed)
|
|
70
|
+
def h
|
|
71
|
+
self
|
|
72
|
+
end
|
|
73
|
+
# Format a number
|
|
74
|
+
# size: number of decimal places
|
|
75
|
+
# zero_as: will display zero as "" (blank), "-" (dash), etc.
|
|
76
|
+
# t: thousands seperator
|
|
77
|
+
# d: decimal seperator
|
|
78
|
+
def f(size=2, zero_as="", t=",", d=".")
|
|
79
|
+
return zero_as if zero?
|
|
80
|
+
num_parts = to_s.split(".")
|
|
81
|
+
x = num_parts[0].gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{t}")
|
|
82
|
+
return x if size == 0
|
|
83
|
+
x << (d + (num_parts[1].to_s + "0000000")[0,size])
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
class String
|
|
87
|
+
# Escape HTML entities
|
|
88
|
+
def h
|
|
89
|
+
gsub(/[&\"<>]/, {'&'=>'&', '"'=>'"', '<'=>'<', '>'=>'>'})
|
|
90
|
+
end
|
|
91
|
+
# Convert a string to a number and format
|
|
92
|
+
# See Numeric.f()
|
|
93
|
+
def f(size=2, zero_as="", t=",", d=".")
|
|
94
|
+
return zero_as if to_f.zero?
|
|
95
|
+
num_parts = split(".")
|
|
96
|
+
x = num_parts[0].gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{t}")
|
|
97
|
+
return x if size == 0
|
|
98
|
+
x << (d + (num_parts[1].to_s + "0000000")[0,size])
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
class Time
|
|
102
|
+
# HTML format
|
|
103
|
+
def h
|
|
104
|
+
to_s.h
|
|
105
|
+
end
|
|
106
|
+
# Format time in strftime
|
|
107
|
+
def f(format='%d-%b-%Y')
|
|
108
|
+
strftime format
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
class TrueClass
|
|
112
|
+
def h
|
|
113
|
+
"true"
|
|
114
|
+
end
|
|
115
|
+
# Format to a selected format (see FalseClass also)
|
|
116
|
+
# Format Options:
|
|
117
|
+
# yn: Yes
|
|
118
|
+
# tf: True
|
|
119
|
+
# icon: glyphicon (Bootstrap)
|
|
120
|
+
# num: 1
|
|
121
|
+
def f(format=:yn)
|
|
122
|
+
case format.to_sym
|
|
123
|
+
when :text
|
|
124
|
+
"True"
|
|
125
|
+
when :icon
|
|
126
|
+
'<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>'
|
|
127
|
+
when :num
|
|
128
|
+
"1"
|
|
129
|
+
else
|
|
130
|
+
raise "Unknown format in TrueClass.f: #{format}. Needs to be :yn, :tf, :icon, or :num."
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Show true as 1
|
|
135
|
+
def to_i
|
|
136
|
+
1
|
|
137
|
+
end
|
|
138
|
+
end
|
data/lib/waxx/pdf.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
|
|
2
|
+
# Released under the Apache Version 2 License. See LICENSE.txt.
|
|
3
|
+
|
|
4
|
+
# require 'prawn' to use PDFs
|
|
5
|
+
|
|
6
|
+
module Waxx::Pdf
|
|
7
|
+
|
|
8
|
+
def new_doc(margin:50, orientation: "portrait", info: {})
|
|
9
|
+
Prawn::Document.new(:margin=>margin, :orientation=>orientation, :info=>info)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def doc_info(
|
|
13
|
+
x,
|
|
14
|
+
title: "Untitled",
|
|
15
|
+
author: nil,
|
|
16
|
+
subject: "",
|
|
17
|
+
keywords: "",
|
|
18
|
+
creator: "WAXX waxx.io",
|
|
19
|
+
producer: "Prawn",
|
|
20
|
+
creation_date: Time.new
|
|
21
|
+
)
|
|
22
|
+
{
|
|
23
|
+
:Title => title,
|
|
24
|
+
:Author => author || "#{x.usr['un']}",
|
|
25
|
+
:Subject => subject,
|
|
26
|
+
:Keywords => keywords,
|
|
27
|
+
:Creator => creator,
|
|
28
|
+
:Producer => producer,
|
|
29
|
+
:CreationDate => creation_date
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def file_path(x)
|
|
34
|
+
"#{Waxx::Root}/tmp/#{Time.new.strftime('%Y%m%dT%H%M%S')}-u#{x.usr['id']}.pdf"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def get
|
|
38
|
+
pdf = new_doc
|
|
39
|
+
pdf.text "Hello from WAXX. You need to implement the get method in your layout. Then call render_file & return_file"
|
|
40
|
+
render_file(x, pdf)
|
|
41
|
+
return_file(x)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def render_file(x, pdf)
|
|
45
|
+
pdf.render_file file_path(x)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def return_file(x)
|
|
49
|
+
File.open(file_path(x), "rb"){|f| x << f.read}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def show_grid(pdf)
|
|
53
|
+
existing_color = pdf.stroke_color?
|
|
54
|
+
pdf.stroke_color Color::RGB.new(230, 230, 255)
|
|
55
|
+
(0..800).step(10){|a|
|
|
56
|
+
pdf.stroke_color Color::RGB.new(130, 130, 255) if (a % 100).zero?
|
|
57
|
+
pdf.line(a,0,a,620).stroke
|
|
58
|
+
pdf.stroke_color Color::RGB.new(230, 230, 255) if (a % 100).zero?
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
(0..620).step(10){|b|
|
|
62
|
+
pdf.stroke_color Color::RGB.new(130, 130, 255) if (b % 100).zero?
|
|
63
|
+
pdf.line(0,b,800,b).stroke
|
|
64
|
+
pdf.stroke_color Color::RGB.new(230, 230, 255) if (b % 100).zero?
|
|
65
|
+
}
|
|
66
|
+
pdf.stroke_color existing_color
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
data/lib/waxx/pg.rb
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
|
|
2
|
+
# Released under the Apache Version 2 License. See LICENSE.txt.
|
|
3
|
+
|
|
4
|
+
##
|
|
5
|
+
# The PostgreSQL Object methods
|
|
6
|
+
module Waxx::Pg
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
attr :app
|
|
10
|
+
attr :db
|
|
11
|
+
attr :table
|
|
12
|
+
attr :columns
|
|
13
|
+
attr :pkey
|
|
14
|
+
attr :joins
|
|
15
|
+
attr :orders
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# Connect to a postgresql database
|
|
19
|
+
#
|
|
20
|
+
# Set in config.yaml:
|
|
21
|
+
# databases:
|
|
22
|
+
# app: postgresql://user:pass@host:port/database
|
|
23
|
+
def connect(str)
|
|
24
|
+
conn = PG.connect( str )
|
|
25
|
+
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
|
|
26
|
+
conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn
|
|
27
|
+
conn
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def init(app:nil, db:"app", table:nil, pk:"id", cols:nil)
|
|
31
|
+
@app ||= (app || App.table_from_class(name)).to_sym
|
|
32
|
+
@db ||= db.to_sym
|
|
33
|
+
@table ||= (table || App.table_from_class(name)).to_sym
|
|
34
|
+
@pkey ||= pk.to_sym
|
|
35
|
+
@columns ||= {}
|
|
36
|
+
@joins ||= {}
|
|
37
|
+
@orders ||= {}
|
|
38
|
+
has(cols) if cols
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def has(opts=nil)
|
|
42
|
+
init if @table.nil?
|
|
43
|
+
return @columns if opts.nil?
|
|
44
|
+
@columns = opts
|
|
45
|
+
@columns.each{|n,v|
|
|
46
|
+
v[:table] = @table
|
|
47
|
+
v[:column] = n
|
|
48
|
+
v[:views] = []
|
|
49
|
+
v[:label] ||= Waxx::Util.label(n)
|
|
50
|
+
@orders[n] = v[:order] || n
|
|
51
|
+
@orders["_#{n}".to_sym] = v[:_order] || "#{n} DESC"
|
|
52
|
+
@pkey = n if v[:pkey]
|
|
53
|
+
build_joins(n, v[:is])
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_joins(n, col_is)
|
|
58
|
+
return if col_is.nil?
|
|
59
|
+
[col_is].flatten.each{|str|
|
|
60
|
+
r, tc = str.split(":")
|
|
61
|
+
t, c = tc.split(".")
|
|
62
|
+
j = c =~ /\+$/ ? "LEFT" : "INNER"
|
|
63
|
+
@joins[r] = {table: @table, col: n.to_s.strip, join: j.to_s.strip, foreign_table: t.to_s.strip, foreign_col: c.to_s.strip.sub('+','')}
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def [](n)
|
|
68
|
+
@columns[n.to_sym]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def /(n)
|
|
72
|
+
@columns[n.to_sym]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def get_cols(*args)
|
|
76
|
+
re = {}
|
|
77
|
+
args.flatten.map{|a| re[a] = @columns[a.to_sym]}
|
|
78
|
+
re
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def runs(opts=nil)
|
|
82
|
+
init if @app.nil?
|
|
83
|
+
return App[@app] if opts.nil?
|
|
84
|
+
App[@app] = opts
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def run(x, act, meth, *args)
|
|
88
|
+
App[@app][act.to_sym][meth.to_sym][x, *args]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def parse_select(select, view)
|
|
92
|
+
raise "Can not define both select and view in Waxx::Object.parse_select (#{name})." if select and view
|
|
93
|
+
return select || "*" if view.nil?
|
|
94
|
+
view.columns.map{|n,c|
|
|
95
|
+
raise "Column #{n} not defined in #{view}" if c.nil?
|
|
96
|
+
if c[:sql_select]
|
|
97
|
+
"#{c[:sql_select]} AS #{n}"
|
|
98
|
+
elsif n != c[:column]
|
|
99
|
+
"#{c[:table]}.#{c[:column]} AS #{n}"
|
|
100
|
+
else
|
|
101
|
+
"#{c[:table]}.#{c[:column]}"
|
|
102
|
+
end
|
|
103
|
+
}.join(", ")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get(x, select:nil, id:nil, joins:nil, where:nil, having:nil, order:nil, limit:nil, offset:nil, view:nil, &blk)
|
|
107
|
+
Waxx.debug "object.get"
|
|
108
|
+
select = parse_select(select, view)
|
|
109
|
+
where = ["#{@table}.#{@pkey} = $1",id] if id and where.nil?
|
|
110
|
+
# Block SQL injection in order clause. All order options must be defined in @orders.
|
|
111
|
+
if order
|
|
112
|
+
# Look in self orders
|
|
113
|
+
if not @orders/order
|
|
114
|
+
# Look in the view's columns
|
|
115
|
+
if view and view.orders/order
|
|
116
|
+
order = view.orders/order
|
|
117
|
+
else
|
|
118
|
+
Waxx.debug("ERROR: Object.get order (#{order}) not found in @orders [#{@orders.keys.join(", ")}]. Sorting by #{@pkey} instead.")
|
|
119
|
+
order = @pkey
|
|
120
|
+
end
|
|
121
|
+
else
|
|
122
|
+
order = @orders/order
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
if joins.nil? and view
|
|
126
|
+
joins = view.joins_to_sql
|
|
127
|
+
end
|
|
128
|
+
q = {select:select, joins:joins, where:where, having:having, order:order, limit:limit, offset:offset}
|
|
129
|
+
yield q if block_given?
|
|
130
|
+
Waxx.debug "object.get.select: #{q[:select]}"
|
|
131
|
+
return [] if q[:select].empty?
|
|
132
|
+
sql = []
|
|
133
|
+
sql << "SELECT #{q[:select] || "*"}"
|
|
134
|
+
sql << "FROM #{@table} #{q[:joins]}"
|
|
135
|
+
sql << "WHERE #{q[:where][0]}" if q[:where]
|
|
136
|
+
sql << "HAVING #{q[:having[0]]}" if q[:having]
|
|
137
|
+
sql << "ORDER BY #{q[:order]}" if q[:order]
|
|
138
|
+
sql << "LIMIT #{q[:limit].to_i}" if q[:limit]
|
|
139
|
+
sql << "OFFSET #{q[:offset].to_i}" if q[:offset]
|
|
140
|
+
vals = []
|
|
141
|
+
vals << q[:where][1] if q[:where] and q[:where][1]
|
|
142
|
+
vals << q[:having][1] if q[:having] and q[:having][1]
|
|
143
|
+
#[sql.join(" "), vals.flatten]
|
|
144
|
+
Waxx.debug sql
|
|
145
|
+
Waxx.debug vals.join(", ")
|
|
146
|
+
x.db[@db].exec(sql.join(" "), vals.flatten)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def get_by_id(x, id, select=nil, view:nil)
|
|
150
|
+
get(x, id: id, select: select, view: view).first
|
|
151
|
+
end
|
|
152
|
+
alias by_id get_by_id
|
|
153
|
+
|
|
154
|
+
def post(x, data, cols:nil, returning:nil, view:nil, &blk)
|
|
155
|
+
if view
|
|
156
|
+
cols = view.columns.select{|n,c| c[:table] == @table}
|
|
157
|
+
else
|
|
158
|
+
cols ||= @columns
|
|
159
|
+
end
|
|
160
|
+
data = blk.call if block_given?
|
|
161
|
+
sql = "INSERT INTO #{@table} ("
|
|
162
|
+
names = []
|
|
163
|
+
vars = []
|
|
164
|
+
vals = []
|
|
165
|
+
ret = []
|
|
166
|
+
i = 1
|
|
167
|
+
cols.each{|n,v|
|
|
168
|
+
if data/n
|
|
169
|
+
names << n.to_s
|
|
170
|
+
vars << "$#{i}"
|
|
171
|
+
vals << cast(v, data/n)
|
|
172
|
+
i += 1
|
|
173
|
+
end
|
|
174
|
+
ret << n.to_s
|
|
175
|
+
}
|
|
176
|
+
sql << names.join(",")
|
|
177
|
+
sql << ") VALUES (#{vars.join(",")})"
|
|
178
|
+
sql << " RETURNING #{returning || ret.join(",")}"
|
|
179
|
+
Waxx.debug(sql)
|
|
180
|
+
Waxx.debug(vals)
|
|
181
|
+
x.db[@db].exec(sql, vals).first
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def put(x, id, data, cols:nil, returning:nil, view:nil, where:nil, &blk)
|
|
185
|
+
if view
|
|
186
|
+
cols = view.columns.select{|n,c| c[:table] == @table}
|
|
187
|
+
else
|
|
188
|
+
cols ||= @columns
|
|
189
|
+
end
|
|
190
|
+
data = blk.call if block_given?
|
|
191
|
+
sql = "UPDATE #{@table} SET "
|
|
192
|
+
set = []
|
|
193
|
+
vals = []
|
|
194
|
+
ret = []
|
|
195
|
+
i = 1
|
|
196
|
+
Waxx.debug "data: #{data}"
|
|
197
|
+
cols.each{|n,v|
|
|
198
|
+
Waxx.debug "col: #{n}: #{v.inspect}"
|
|
199
|
+
if data.has_key? n.to_s or data.has_key? n.to_sym
|
|
200
|
+
set << "#{n} = $#{i}"
|
|
201
|
+
vals << cast(v, data/n)
|
|
202
|
+
ret << n.to_s
|
|
203
|
+
i += 1
|
|
204
|
+
end
|
|
205
|
+
}
|
|
206
|
+
sql << set.join(",")
|
|
207
|
+
sql << " WHERE #{@pkey} = $#{i} #{where} RETURNING #{returning || ret.join(",")}"
|
|
208
|
+
vals << id
|
|
209
|
+
Waxx.debug(sql)
|
|
210
|
+
Waxx.debug(vals)
|
|
211
|
+
x.db[@db].exec(sql, vals).first
|
|
212
|
+
end
|
|
213
|
+
alias patch put
|
|
214
|
+
|
|
215
|
+
def put_post(x, id, data, cols:nil, returning:nil, view: nil)
|
|
216
|
+
q = nil
|
|
217
|
+
q = get_by_id(x, id, @pkey) if id.to_i > 0
|
|
218
|
+
return post(x, data, cols: cols, returning: returning, view: view) if q.nil?
|
|
219
|
+
put(x, id, data, cols: cols, returning: returning, view: view)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def cast(col, val)
|
|
223
|
+
case col[:type].to_sym
|
|
224
|
+
when :int
|
|
225
|
+
val.to_s.empty? ? nil : val.to_i
|
|
226
|
+
when :float, :numeric
|
|
227
|
+
val.to_s.empty? ? nil : val.to_f
|
|
228
|
+
else
|
|
229
|
+
val
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def delete(x, id)
|
|
234
|
+
x.db[@db].exec("DELETE FROM #{@table} WHERE #{@pkey} = $1", [id])
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def order(req_order, default_order='')
|
|
238
|
+
return default_order if req_order.nil?
|
|
239
|
+
return orders[req_order.to_sym] if orders.has_key? req_order.to_sym
|
|
240
|
+
@pkey
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def debug(str, level=3)
|
|
244
|
+
Waxx.debug(str, level)
|
|
245
|
+
end
|
|
246
|
+
end
|