twowaysql 0.2.0

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.
Files changed (39) hide show
  1. data/History.txt +3 -0
  2. data/License.txt +13 -0
  3. data/Manifest.txt +38 -0
  4. data/README.txt +382 -0
  5. data/Rakefile +4 -0
  6. data/config/hoe.rb +73 -0
  7. data/config/requirements.rb +15 -0
  8. data/issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml +18 -0
  9. data/issues/issue-39023ea09e17e2d64bcef03aa59cdfe38b78ad5b.yaml +26 -0
  10. data/issues/issue-4bc308d55ae91f266e656162a4147d356de1166c.yaml +24 -0
  11. data/issues/issue-897995fa10377eabdf597e8e7692f17087c76923.yaml +26 -0
  12. data/issues/issue-bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8.yaml +26 -0
  13. data/issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml +18 -0
  14. data/issues/issue-f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a.yaml +18 -0
  15. data/issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml +18 -0
  16. data/issues/project.yaml +16 -0
  17. data/lib/twowaysql/node.rb +239 -0
  18. data/lib/twowaysql/parser.rb +489 -0
  19. data/lib/twowaysql/parser.y +226 -0
  20. data/lib/twowaysql/template.rb +75 -0
  21. data/lib/twowaysql/version.rb +9 -0
  22. data/lib/twowaysql.rb +6 -0
  23. data/script/console +10 -0
  24. data/script/destroy +14 -0
  25. data/script/generate +14 -0
  26. data/script/txt2html +82 -0
  27. data/setup.rb +1585 -0
  28. data/spec/large_sql_spec.rb +142 -0
  29. data/spec/learning_regex_spec.rb +234 -0
  30. data/spec/spec.opts +0 -0
  31. data/spec/spec_helper.rb +10 -0
  32. data/spec/twowaysql_spec.rb +736 -0
  33. data/tasks/deployment.rake +53 -0
  34. data/tasks/ditz.rake +8 -0
  35. data/tasks/environment.rake +7 -0
  36. data/tasks/racc.rake +23 -0
  37. data/tasks/rspec.rake +21 -0
  38. data/tasks/website.rake +17 -0
  39. metadata +104 -0
@@ -0,0 +1,75 @@
1
+ require 'forwardable'
2
+
3
+ module TwoWaySQL
4
+
5
+ # TwoWaySQL::Template represents template object, acts as a Facade for this package.
6
+ # Template is stateless, reentrant object so template object is cacheable.
7
+ class Template
8
+
9
+ # parse TwoWaySQL-style SQL then return TwoWaySQL::Template object
10
+ #
11
+ # === Usage
12
+ #
13
+ # sql = "SELECT * FROM emp WHERE job = /*ctx[:job]*/'CLERK' AND deptno = /*ctx[:deptno]*/20"
14
+ # template = TwoWaySQL::Template.parse(sql)
15
+ #
16
+ # === Arguments
17
+ #
18
+ # +sql_io+::
19
+ # IO-like object that contains TwoWaySQL-style SQL
20
+ #
21
+ # +opts+::
22
+ # (optional) Hash of parse options to pass internal lexer. default is empty hash.
23
+ #
24
+ # === Return
25
+ #
26
+ # TwoWaySQL::Template object that represents parse result
27
+ #
28
+ def Template.parse(sql_io, opts={})
29
+ parser = Parser.new(opts)
30
+ root = parser.parse(sql_io)
31
+ Template.new(root)
32
+ end
33
+
34
+ # merge data with template
35
+ #
36
+ # === Usage
37
+ #
38
+ # merged = template.merge(:job => "HOGE", :deptno => 30)
39
+ # merged.sql #=> "SELECT * FROM emp WHERE job = ? AND deptno = ?"
40
+ # merged.bound_variables #=> ["HOGE", 30]
41
+ #
42
+ # === Arguments
43
+ #
44
+ # +data+::
45
+ # Hash-like object that contains data to merge. This data will evaluated as name 'ctx'.
46
+ #
47
+ # === Return
48
+ #
49
+ # TwoWaySQL::Result object that represents merge result
50
+ #
51
+ def merge(data)
52
+ c = Context.new(data)
53
+ @root.accept(c)
54
+ Result.new(c)
55
+ end
56
+ alias mungle merge
57
+
58
+ protected
59
+ def initialize(root)
60
+ @root = root
61
+ end
62
+ end
63
+
64
+
65
+ # TwoWaySQL::Result represents merge result of template and data.
66
+ # it contains SQL string with placeholders, and bound variables associated with placeholders.
67
+ class Result
68
+ extend Forwardable
69
+ def initialize(context)
70
+ @context = context
71
+ end
72
+ def_delegators :@context, :sql, :bound_variables
73
+ end
74
+
75
+ end
@@ -0,0 +1,9 @@
1
+ module TwoWaySQL
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 2
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/lib/twowaysql.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'twowaysql/node'
5
+ require 'twowaysql/parser'
6
+ require 'twowaysql/template'
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/twowaysql.rb'}"
9
+ puts "Loading twowaysql gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'twowaysql' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'twowaysql'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
19
+
20
+ version = TwoWaySQL::VERSION::STRING
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)