mao 0.0.6 → 0.0.7

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.
data/.gitignore CHANGED
@@ -1 +1,18 @@
1
- /pkg
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
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
@@ -1,8 +1,13 @@
1
1
  require 'rspec/core/rake_task'
2
2
  require 'bundler/gem_tasks'
3
+ require 'rdoc/task'
3
4
 
4
5
  task :default => :spec
5
6
 
6
7
  RSpec::Core::RakeTask.new
7
8
 
9
+ RDoc::Task.new do |i|
10
+ i.rdoc_files = FileList['lib/**/*.rb']
11
+ end
12
+
8
13
  # vim: set sw=2 et cc=80:
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
- Joins/eager loads. What syntax? How do we prevent unexpected blowouts?
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 assume) that the primary table's columns come first, and secondary table's after; then just pick off the first n cols of a result tuple (where n is number of cols in primary table) and assign them to the primary table, and the remaining m (where m is no. of cols in secondary) to secondary.
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
- # HACK(arlen): ? Calling this "nil?" results in the world crashing down
83
- # around us. But it seems a pity to have this be not-quite-like-Ruby. Would
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
@@ -1,5 +1,7 @@
1
1
  module Mao
2
- VERSION = "0.0.6"
2
+ # The version of the last release of Mao made. Increment when releasing a
3
+ # new gem.
4
+ VERSION = "0.0.7"
3
5
  end
4
6
 
5
7
  # vim: set sw=2 cc=80 et:
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.6
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-11-15 00:00:00.000000000 Z
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.