mao 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -1
- data/README.md +10 -1
- data/Rakefile +5 -0
- data/TODO +8 -3
- data/lib/mao/filter.rb +19 -3
- data/lib/mao/query.rb +13 -0
- data/lib/mao/version.rb +3 -1
- metadata +2 -4
- data/Gemfile.lock +0 -28
- data/thoughts.rb +0 -42
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,18 @@
|
|
1
|
-
# Mao [![Build Status](https://secure.travis-ci.org/unnali/mao.png)](http://travis-ci.org/unnali/mao)
|
1
|
+
# Mao [![Build Status](https://secure.travis-ci.org/unnali/mao.png)](http://travis-ci.org/unnali/mao) [![Dependency Status](https://gemnasium.com/unnali/mao.png)](https://gemnasium.com/unnali/mao)
|
2
2
|
|
3
3
|
**Mao Ain't an ORM.**
|
4
4
|
|
5
5
|
## mission/tenets
|
6
6
|
|
7
|
+
1. From the code you have written, it should be sufficiently declarative and
|
8
|
+
map sufficiently predictably to SQL that you can predict the SQL produced.
|
9
|
+
|
10
|
+
## releasing
|
11
|
+
|
12
|
+
1. Bump `lib/mao/version.rb` as appropriate.
|
13
|
+
2. Commit same.
|
14
|
+
3. `rake release`
|
15
|
+
|
7
16
|
## authorship
|
8
17
|
|
9
18
|
* [Timothy Leslie Allen](https://github.com/timothyleslieallen).
|
data/Rakefile
CHANGED
data/TODO
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
Test that PG::Connection#escape_literal-less Mao.escape_literal works with
|
2
|
+
binary data.
|
1
3
|
Specify error handling at all levels.
|
2
|
-
|
3
|
-
- no auto subqueries, etc. Thinner wrapper over SQL than AR.
|
4
|
+
Reconnection.
|
4
5
|
|
5
|
-
Do JOINs without all the "c1" "c2" "c3" business; assume (= check we can
|
6
|
+
Do JOINs without all the "c1" "c2" "c3" business; assume (= check we can
|
7
|
+
assume) that the primary table's columns come first, and secondary table's
|
8
|
+
after; then just pick off the first n cols of a result tuple (where n is number
|
9
|
+
of cols in primary table) and assign them to the primary table, and the
|
10
|
+
remaining m (where m is no. of cols in secondary) to secondary.
|
data/lib/mao/filter.rb
CHANGED
@@ -24,10 +24,13 @@ module Mao::Filter
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
# Initialize a filter object with the given options. Filters are intended to
|
28
|
+
# be used immutably, and all methods on same return new, immutable filters.
|
27
29
|
def initialize(options={})
|
28
30
|
@options = options.freeze
|
29
31
|
end
|
30
32
|
|
33
|
+
# The options hash for this filter.
|
31
34
|
attr_reader :options
|
32
35
|
|
33
36
|
# Returns an AND filter where the current object is the LHS and +rhs+ is the
|
@@ -79,9 +82,9 @@ module Mao::Filter
|
|
79
82
|
end
|
80
83
|
|
81
84
|
# Returns a filter where the current object is checked if it IS NULL.
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# it be better to make #==(nil) map to IS NULL instead of = NULL?
|
85
|
+
# HACK(arlen): ? Calling this "nil?" results in the world crashing down
|
86
|
+
# around us. But it seems a pity to have this be not-quite-like-Ruby.
|
87
|
+
# Would it be better to make #==(nil) map to IS NULL instead of = NULL?
|
85
88
|
def null?
|
86
89
|
Mao::Filter::Binary.new(:op => 'IS', :lhs => self, :rhs => nil)
|
87
90
|
end
|
@@ -92,9 +95,12 @@ module Mao::Filter
|
|
92
95
|
Mao::Filter::Binary.new(:op => 'IN', :lhs => self, :rhs => rhs)
|
93
96
|
end
|
94
97
|
|
98
|
+
# A reference to a column('s value) in a filter.
|
95
99
|
class Column
|
96
100
|
include Mao::Filter
|
97
101
|
|
102
|
+
# Produces an array which becomes part of the resulting Mao::Query's
|
103
|
+
# options, used by Mao::Query#sql.
|
98
104
|
def finalize
|
99
105
|
if @options[:table]
|
100
106
|
[:Column, @options[:table], @options[:name]]
|
@@ -103,14 +109,19 @@ module Mao::Filter
|
|
103
109
|
end
|
104
110
|
end
|
105
111
|
|
112
|
+
# Used by Mao::Filter.sql to generate the actual SQL for a column
|
113
|
+
# reference.
|
106
114
|
def self.sql(*opts)
|
107
115
|
opts.map {|i| Mao.quote_ident(i.to_s)}.join(".")
|
108
116
|
end
|
109
117
|
end
|
110
118
|
|
119
|
+
# A binary operation on two filters.
|
111
120
|
class Binary
|
112
121
|
include Mao::Filter
|
113
122
|
|
123
|
+
# Produces an array which becomes part of the resulting Mao::Query's
|
124
|
+
# options, used by Mao::Query#sql.
|
114
125
|
def finalize
|
115
126
|
[:Binary,
|
116
127
|
@options[:op],
|
@@ -118,6 +129,8 @@ module Mao::Filter
|
|
118
129
|
Mao::Filter.finalize_or_literal(@options[:rhs])]
|
119
130
|
end
|
120
131
|
|
132
|
+
# Used by Mao::Filter.sql to generate the actual SQL for a column
|
133
|
+
# reference.
|
121
134
|
def self.sql(op, lhs, rhs)
|
122
135
|
s = "("
|
123
136
|
s << Mao::Filter.sql(lhs)
|
@@ -135,6 +148,9 @@ module Mao::Filter
|
|
135
148
|
# which checks if it belongs to a column, and if so, constructs a
|
136
149
|
# Mao::Filter::Column.
|
137
150
|
class Table
|
151
|
+
# Constructs a Table; +query+ is the Mao::Query instance, and +explicit+
|
152
|
+
# refers to whether we need to explicitly name tables in the generated SQL.
|
153
|
+
# (e.g. when a JOIN is being performed)
|
138
154
|
def initialize(query, explicit)
|
139
155
|
@query = query
|
140
156
|
@explicit = explicit
|
data/lib/mao/query.rb
CHANGED
@@ -9,10 +9,12 @@ class Mao::Query
|
|
9
9
|
|
10
10
|
# A container for text that should be inserted raw into a query.
|
11
11
|
class Raw
|
12
|
+
# Creates the Mao::Query::Raw with SQL +text+.
|
12
13
|
def initialize(text)
|
13
14
|
@text = text
|
14
15
|
end
|
15
16
|
|
17
|
+
# The raw SQL text.
|
16
18
|
attr_reader :text
|
17
19
|
end
|
18
20
|
|
@@ -21,6 +23,9 @@ class Mao::Query
|
|
21
23
|
Raw.new(text).freeze
|
22
24
|
end
|
23
25
|
|
26
|
+
# Constructs the Query with reference to a table named +table+, and immutable
|
27
|
+
# options hash +options+. +col_types+ is column information for the table,
|
28
|
+
# usually populated by a prior invocation of Mao::Query.new.
|
24
29
|
def initialize(table, options={}, col_types=nil)
|
25
30
|
@table, @options = table.to_sym, options.freeze
|
26
31
|
|
@@ -43,8 +48,14 @@ class Mao::Query
|
|
43
48
|
@col_types = col_types.freeze
|
44
49
|
end
|
45
50
|
|
51
|
+
# A symbol of the name of the table this Query points to.
|
46
52
|
attr_reader :table
|
53
|
+
|
54
|
+
# The immutable options hash of this Query instance.
|
47
55
|
attr_reader :options
|
56
|
+
|
57
|
+
# The cached information about columns and their types for the table being
|
58
|
+
# referred to.
|
48
59
|
attr_reader :col_types
|
49
60
|
|
50
61
|
# Returns a new Mao::Query with +options+ merged into the options of this
|
@@ -368,6 +379,8 @@ class Mao::Query
|
|
368
379
|
|
369
380
|
private
|
370
381
|
|
382
|
+
# Checks that +column+ is a valid column reference in +table+, given
|
383
|
+
# +col_types+ for the table.
|
371
384
|
def check_column column, table, col_types
|
372
385
|
unless column.is_a? Symbol
|
373
386
|
raise ArgumentError, "#{column.inspect} not a Symbol"
|
data/lib/mao/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mao
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-12-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: pg
|
@@ -73,7 +73,6 @@ files:
|
|
73
73
|
- .rspec
|
74
74
|
- .travis.yml
|
75
75
|
- Gemfile
|
76
|
-
- Gemfile.lock
|
77
76
|
- README.md
|
78
77
|
- Rakefile
|
79
78
|
- TODO
|
@@ -87,7 +86,6 @@ files:
|
|
87
86
|
- spec/mao_spec.rb
|
88
87
|
- spec/query_spec.rb
|
89
88
|
- spec/spec_helper.rb
|
90
|
-
- thoughts.rb
|
91
89
|
homepage: https://github.com/unnali/mao
|
92
90
|
licenses: []
|
93
91
|
post_install_message:
|
data/Gemfile.lock
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
mao (0.0.4)
|
5
|
-
pg (~> 0.14.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
diff-lcs (1.1.3)
|
11
|
-
pg (0.14.1)
|
12
|
-
rake (0.9.2.2)
|
13
|
-
rspec (2.11.0)
|
14
|
-
rspec-core (~> 2.11.0)
|
15
|
-
rspec-expectations (~> 2.11.0)
|
16
|
-
rspec-mocks (~> 2.11.0)
|
17
|
-
rspec-core (2.11.1)
|
18
|
-
rspec-expectations (2.11.3)
|
19
|
-
diff-lcs (~> 1.1.3)
|
20
|
-
rspec-mocks (2.11.3)
|
21
|
-
|
22
|
-
PLATFORMS
|
23
|
-
ruby
|
24
|
-
|
25
|
-
DEPENDENCIES
|
26
|
-
mao!
|
27
|
-
rake
|
28
|
-
rspec
|
data/thoughts.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
X.trans do
|
2
|
-
X.query(:tblSamuraiUser).join { ... }.where {
|
3
|
-
upp = tblSamuraiUserProduct
|
4
|
-
|
5
|
-
upp.userProductId == 188...
|
6
|
-
|
7
|
-
|
8
|
-
first_cond = (email == "arlen@noblesamurai.com").and(userId > 10000)
|
9
|
-
second_cond = x.and(y).and(z)
|
10
|
-
|
11
|
-
blah = tblSamuraiUserProduct.columnName == xyzzy
|
12
|
-
|
13
|
-
first_cond.or second_cond.or blah
|
14
|
-
}
|
15
|
-
|
16
|
-
my_new_record = my_old_record.merge(changes)
|
17
|
-
|
18
|
-
X.update(:tblSamuraiUser).where { userId == 610610 }.update(changes)
|
19
|
-
end
|
20
|
-
|
21
|
-
X.query(:tblSamuraiUser).where(lambda {email == "arlen@noblesamurai.com"}, lambda {userId > 10000})
|
22
|
-
|
23
|
-
#Tim's thoughts:
|
24
|
-
#
|
25
|
-
#- We need to know what we think of statically defined r'ships b/w tables vs defining everything in place where the query is performed.
|
26
|
-
# Is the ActiveRecord way of defining r'ships b/w tables a good model for us?
|
27
|
-
# Or do we have some alternative way of statically defining this stuff? Or do we dynamically infer it?
|
28
|
-
#
|
29
|
-
# I am thinking we need a means to join which is based again on a simple hash. For example, the hash
|
30
|
-
# could look like: {:from => :tblSamuraiUser.id, :to => tblSamuraiUserProduct.user_id}
|
31
|
-
# Then, the user could define these hash as constants, eg UserToUserProduct = blah
|
32
|
-
# The joins could then be brought in to the query object (perhaps a .joins method, which can either take a single hash or an array),
|
33
|
-
# as with a :joins key, which might map to an array of joins options hashes.
|
34
|
-
#
|
35
|
-
# Anyway, those are my thoughts for now, we can chat further!
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# Tenet:
|
40
|
-
#
|
41
|
-
# From the code you have written, it should be sufficiently declarative and map
|
42
|
-
# sufficiently predictably to SQL that you can predict the SQL produced.
|