dumbo 0.0.1 → 0.0.3

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +1 -1
  4. data/bin/dumbo +65 -24
  5. data/config/boot.rb +2 -3
  6. data/dumbo.gemspec +1 -2
  7. data/lib/dumbo.rb +17 -16
  8. data/lib/dumbo/aggregate.rb +3 -5
  9. data/lib/dumbo/base_type.rb +17 -17
  10. data/lib/dumbo/binding_loader.rb +50 -0
  11. data/lib/dumbo/cast.rb +5 -5
  12. data/lib/dumbo/composite_type.rb +4 -4
  13. data/lib/dumbo/db_task.rb +6 -5
  14. data/lib/dumbo/dependency_resolver.rb +17 -18
  15. data/lib/dumbo/enum_type.rb +3 -4
  16. data/lib/dumbo/extension.rb +64 -20
  17. data/lib/dumbo/extension_migrator.rb +11 -11
  18. data/lib/dumbo/extension_version.rb +29 -11
  19. data/lib/dumbo/function.rb +21 -21
  20. data/lib/dumbo/operator.rb +4 -6
  21. data/lib/dumbo/pg_object.rb +17 -21
  22. data/lib/dumbo/rake_task.rb +63 -53
  23. data/lib/dumbo/range_type.rb +6 -9
  24. data/lib/dumbo/test.rb +8 -0
  25. data/lib/dumbo/test/fixture.rb +51 -0
  26. data/lib/dumbo/test/helper.rb +64 -0
  27. data/lib/dumbo/test/matchers.rb +76 -0
  28. data/lib/dumbo/test/regression_helper.rb +20 -0
  29. data/lib/dumbo/test/silence_unknown_oid.rb +12 -0
  30. data/lib/dumbo/type.rb +3 -4
  31. data/lib/dumbo/version.rb +1 -1
  32. data/spec/aggregate_spec.rb +9 -10
  33. data/spec/cast_spec.rb +5 -5
  34. data/spec/{Makefile → dumbo_sample/Makefile} +4 -0
  35. data/spec/{dumbo_sample--0.0.1.sql → dumbo_sample/dumbo_sample--0.0.1.sql} +0 -0
  36. data/spec/{dumbo_sample--0.0.2.sql → dumbo_sample/dumbo_sample--0.0.2.sql} +0 -0
  37. data/spec/dumbo_sample/dumbo_sample--0.0.3.sql +7 -0
  38. data/spec/dumbo_sample/dumbo_sample--0.0.4.sql +13 -0
  39. data/spec/{dumbo_sample.control → dumbo_sample/dumbo_sample.control} +0 -0
  40. data/spec/dumbo_sample/src/dumbo_sample.c +13 -0
  41. data/spec/dumbo_sample/src/dumbo_sample.h +17 -0
  42. data/spec/extension_migrator_spec.rb +12 -11
  43. data/spec/extension_spec.rb +41 -12
  44. data/spec/extension_version_spec.rb +27 -0
  45. data/spec/operator_spec.rb +6 -7
  46. data/spec/spec_helper.rb +15 -9
  47. data/spec/support/extension_helper.rb +31 -0
  48. data/spec/support/silence_unknown_oid.rb +12 -0
  49. data/spec/type_spec.rb +59 -55
  50. data/template/Rakefile +6 -6
  51. data/template/spec/sample_spec.rb.erb +1 -1
  52. metadata +33 -31
  53. data/config/database.yml +0 -31
  54. data/lib/tasks/db.rake +0 -52
  55. data/lib/tasks/dumbo.rake +0 -23
  56. data/spec/support/sql_helper.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c38d6d2545804ea840a234c51c3d912fc2988a3
4
- data.tar.gz: a1ace87c6b8469126e95a1eb94f9a503bcd93483
3
+ metadata.gz: 82e2e9299fa177d4e41fdc7b8c3417476190fff8
4
+ data.tar.gz: 5cf24b1b10829fcacf94016bd2fd29e21ab005d1
5
5
  SHA512:
6
- metadata.gz: 6043bb12bfee32add950dd79093d41c3ea70732028749ccf8db79413d2e2219e8b3d5b197695255c4cba3d24ce4e38b3e3a2bdfc83522095ba9b85466fbf4623
7
- data.tar.gz: ac5757b0c2dee69ecd5c0d962d3e0f4557b1937b5c08f63c0d3d3210134ef11975803a675e01f2770df35e250865e1331404577a42b246d8043406492394c778
6
+ metadata.gz: d08e465e241b15fb5796af82ecbe8480e37e22be2728bf96255e7cd00fee75e9d17073889dcead4af350eb9a22755e628267e59b23ebdfdd2977e552e6d6a2ee
7
+ data.tar.gz: 23e9fa7f1b2433e0d4c0641fe432c08674bbb3171bf66083c5dc032d7655acec3b0c93a3bf4523cdab21961499526bdf66f009a431c87df0dbc573e6f6b6b319
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ config/database.yml
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in dumbo.gemspec
4
- gemspec
4
+ gemspec
data/bin/dumbo CHANGED
@@ -3,25 +3,24 @@ require 'thor'
3
3
  require 'thor/group'
4
4
  require 'erubis'
5
5
  require 'fileutils'
6
+ require 'pathname'
6
7
 
7
8
  module Cli
8
9
  class Dumbo < Thor
10
+ desc 'new name', 'creates a new extension skeleton'
9
11
 
10
- desc "new name", "creates a new extension skeleton"
11
-
12
- def new(name, initial_version='0.0.1')
13
- FileUtils.mkdir_p("#{name}/sql")
14
- FileUtils.mkdir_p("#{name}/src")
15
- FileUtils.mkdir_p("#{name}/spec/support")
16
- FileUtils.mkdir_p("#{name}/config")
17
- FileUtils.mkdir_p("#{name}/lib/tasks")
12
+ def new(name, initial_version = '0.0.1')
13
+ mkdir("#{name}/sql")
14
+ mkdir("#{name}/src")
15
+ mkdir("#{name}/spec")
16
+ mkdir("#{name}/config")
17
+ mkdir("#{name}/lib/tasks")
18
18
 
19
19
  spec_helper = Dir.glob(File.expand_path('../../spec/spec_helper.rb', __FILE__))
20
20
  spec_helper += Dir.glob(File.expand_path('../../spec/support', __FILE__))
21
21
 
22
- FileUtils.cp_r spec_helper, "#{name}/spec/"
23
-
24
- FileUtils.cp File.expand_path('../../config/boot.rb', __FILE__), "#{name}/config/"
22
+ cp spec_helper, "#{name}/spec"
23
+ cp File.expand_path('../../config/boot.rb', __FILE__), "#{name}/config"
25
24
 
26
25
  template_path = File.expand_path('../../template', __FILE__)
27
26
 
@@ -30,29 +29,71 @@ module Cli
30
29
  dest_name = pathname.relative_path_from Pathname.new(template_path)
31
30
 
32
31
  if pathname.directory?
33
- FileUtils.mkdir_p("#{name}/#{dest_name}")
32
+ mkdir("#{name}/#{dest_name}", true)
34
33
  next
35
34
  end
36
35
 
37
- if dest_name.extname =='.erb'
36
+ if dest_name.extname == '.erb'
38
37
  eruby = Erubis::Eruby.new(File.read(template))
39
- File.open("#{name}/#{dest_name.sub_ext('')}",'w') do |f|
40
- f.puts eruby.result({ext_name: name})
41
- end
38
+ content = eruby.result(ext_name: name)
39
+ create "#{name}/#{dest_name.sub_ext('')}", content
40
+ else
41
+ cp template, "#{name}/#{dest_name}"
42
+ end
43
+ end
44
+
45
+ create "#{name}/#{name}.control", <<-STR
46
+ # #{name} extension
47
+ comment = 'my awesome extension'
48
+ default_version = '#{initial_version}'
49
+ relocatable = true
50
+ requires = ''
51
+ STR
52
+ end
53
+
54
+ no_commands do
55
+ def mkdir(path, silent_skip = false)
56
+ if File.directory?(path)
57
+ say_status('skip', "#{path}", :yellow) unless silent_skip
58
+ else
59
+ FileUtils.mkdir_p(path)
60
+ say_status('create', "#{path}")
61
+ end
62
+ end
63
+
64
+ def create(path, content, silent_skip = false)
65
+ if File.exist? path
66
+ say_status('skip', path, :yellow) unless silent_skip
42
67
  else
43
- FileUtils.cp template, "#{name}/#{dest_name}"
68
+ File.open(path, 'w') do |f|
69
+ f.puts content
70
+ end
71
+ say_status('create', path)
44
72
  end
45
73
  end
46
74
 
47
- File.open("#{name}/#{name}.control",'w') do |f|
48
- f.puts "# #{name} extension"
49
- f.puts "comment = 'my awesome extension'"
50
- f.puts "default_version = '#{initial_version}'"
51
- f.puts "relocatable = true"
52
- f.puts "requires = ''"
75
+ def cp(src, dest, silent_skip = false)
76
+ Array(src).each do |p|
77
+ path = Pathname.new(p)
78
+ if File.directory?(dest)
79
+ if File.exist?("#{dest}/#{path.basename}")
80
+ say_status('skip', "#{dest}/#{path.basename}", :yellow) unless silent_skip
81
+ else
82
+ FileUtils.cp_r p, dest
83
+ say_status('create', "#{dest}/#{path.basename}")
84
+ end
85
+ else
86
+ if File.exist?(dest)
87
+ say_status('skip', dest, :yellow) unless silent_skip
88
+ else
89
+ FileUtils.cp_r p, dest
90
+ say_status('create', dest)
91
+ end
92
+ end
93
+ end
53
94
  end
54
95
  end
55
96
  end
56
97
  end
57
98
 
58
- Cli::Dumbo.start(ARGV)
99
+ Cli::Dumbo.start(ARGV)
@@ -1,15 +1,14 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $LOAD_PATH.unshift File.expand_path('../..', __FILE__)
2
2
 
3
3
  # Set up gems listed in the Gemfile.
4
4
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5
5
  ENV['DUMBO_ENV'] ||= 'development'
6
6
 
7
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
8
8
  Bundler.require(:default, ENV['DUMBO_ENV'].to_sym)
9
9
 
10
10
  def db_config
11
11
  @config ||= YAML.load_file('config/database.yml')
12
12
  end
13
13
 
14
-
15
14
  ActiveRecord::Base.establish_connection db_config[ENV['DUMBO_ENV']]
@@ -19,8 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_dependency "rake"
21
21
  spec.add_dependency 'erubis'
22
- spec.add_dependency 'rspec', '~> 2.14.0'
23
- spec.add_dependency'factory_girl', '~> 4.0'
22
+ spec.add_dependency 'rspec', '~> 3.0.0'
24
23
  spec.add_dependency 'activerecord'
25
24
  spec.add_dependency 'pg', '> 0.17'
26
25
 
@@ -1,20 +1,21 @@
1
1
  require 'active_record'
2
- require "dumbo/version"
3
- require "dumbo/pg_object"
4
- require "dumbo/type"
5
- require "dumbo/function"
6
- require "dumbo/cast"
7
- require "dumbo/base_type"
8
- require "dumbo/aggregate"
9
- require "dumbo/composite_type"
10
- require "dumbo/dependency_resolver"
11
- require "dumbo/enum_type"
12
- require "dumbo/extension"
13
- require "dumbo/extension_migrator"
14
- require "dumbo/extension_version"
15
- require "dumbo/operator"
16
- require "dumbo/range_type"
17
- require "dumbo/version"
2
+ require 'dumbo/version'
3
+ require 'dumbo/pg_object'
4
+ require 'dumbo/type'
5
+ require 'dumbo/function'
6
+ require 'dumbo/cast'
7
+ require 'dumbo/base_type'
8
+ require 'dumbo/aggregate'
9
+ require 'dumbo/composite_type'
10
+ require 'dumbo/dependency_resolver'
11
+ require 'dumbo/enum_type'
12
+ require 'dumbo/extension'
13
+ require 'dumbo/extension_migrator'
14
+ require 'dumbo/extension_version'
15
+ require 'dumbo/operator'
16
+ require 'dumbo/range_type'
17
+ require 'dumbo/version'
18
+ require 'dumbo/binding_loader'
18
19
 
19
20
  module Dumbo
20
21
  # Your code goes here...
@@ -30,14 +30,13 @@ module Dumbo
30
30
  WHERE aggfnoid = #{oid}
31
31
  SQL
32
32
 
33
- result.first.each do |k,v|
34
- send("#{k}=",v) rescue nil
33
+ result.first.each do |k, v|
34
+ send("#{k}=", v) rescue nil
35
35
  end
36
36
 
37
37
  result.first
38
38
  end
39
39
 
40
-
41
40
  def to_sql
42
41
  attributes = []
43
42
  attributes << "SFUNC = #{sfunc}"
@@ -52,6 +51,5 @@ module Dumbo
52
51
  );
53
52
  SQL
54
53
  end
55
-
56
54
  end
57
- end
55
+ end
@@ -1,18 +1,18 @@
1
1
  module Dumbo
2
2
  class BaseType < Type
3
- attr_accessor :input_function,
4
- :output_function,
5
- :receive_function,
6
- :send_function,
7
- :analyze_function,
8
- :category,
9
- :default,
10
- :alignment,
11
- :storage,
12
- :type,
13
- :internallength,
14
- :attribute_name,
15
- :typrelid
3
+ attr_accessor :input_function,
4
+ :output_function,
5
+ :receive_function,
6
+ :send_function,
7
+ :analyze_function,
8
+ :category,
9
+ :default,
10
+ :alignment,
11
+ :storage,
12
+ :type,
13
+ :internallength,
14
+ :attribute_name,
15
+ :typrelid
16
16
 
17
17
  def load_attributes
18
18
  sql = <<-SQL
@@ -44,15 +44,15 @@ module Dumbo
44
44
  SQL
45
45
 
46
46
  result = execute sql
47
- result.first.each do |k,v|
48
- send("#{k}=",v) rescue nil
47
+ result.first.each do |k, v|
48
+ send("#{k}=", v) rescue nil
49
49
  end
50
50
 
51
51
  result.first
52
52
  end
53
53
 
54
54
  def to_sql
55
- <<-SQL.gsub(/^ {8}/, '')
55
+ <<-SQL.gsub(/^ {8}/, '')
56
56
  CREATE TYPE #{name}(
57
57
  INPUT=#{input_function},
58
58
  OUTPUT=#{output_function},
@@ -68,4 +68,4 @@ module Dumbo
68
68
  SQL
69
69
  end
70
70
  end
71
- end
71
+ end
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+ module Dumbo
3
+ class BindingLoader
4
+
5
+ def self.load_pattern
6
+ /\s*--\s*load +([^\s'";]+)/
7
+ end
8
+
9
+ def initialize(file)
10
+ @file = file
11
+ end
12
+
13
+ def load
14
+ load_list.reduce({}) do |result, file|
15
+ yaml = Pathname.new(file).sub_ext('.yml')
16
+ bind = YAML.load_file(yaml)
17
+
18
+ result.merge(bind)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def load_list
25
+ files = []
26
+ IO.foreach(@file) do |line|
27
+ catch(:done) do
28
+ load_file = parse(line)
29
+ files << load_file if load_file
30
+ end
31
+ end
32
+ files
33
+ end
34
+
35
+ def parse(line)
36
+ return Regexp.last_match[1] if encoded_line(line) =~ BindingLoader.load_pattern
37
+
38
+ # end of first commenting block we're done.
39
+ throw :done unless line =~ /--/
40
+ end
41
+
42
+ def encoded_line(line)
43
+ if String.method_defined?(:encode)
44
+ line.encode!('UTF-8', 'UTF-8', invalid: :replace)
45
+ else
46
+ line
47
+ end
48
+ end
49
+ end
50
+ end
@@ -23,21 +23,21 @@ module Dumbo
23
23
  WHERE ca.oid = #{oid}
24
24
  SQL
25
25
 
26
- result.first.each do |k,v|
27
- send("#{k}=",v) rescue nil
26
+ result.first.each do |k, v|
27
+ send("#{k}=", v) rescue nil
28
28
  end
29
29
 
30
30
  result.first
31
31
  end
32
32
 
33
33
  def drop
34
- "DROP CAST (#{source_type} AS #{target_type})"
34
+ "DROP CAST (#{source_type} AS #{target_type});"
35
35
  end
36
36
 
37
37
  def to_sql
38
38
  attributes = []
39
39
  attributes << "WITH FUNCTION #{function_name}(#{source_type})" if function_name
40
- attributes << "WITHOUT FUNCTION" unless function_name
40
+ attributes << 'WITHOUT FUNCTION' unless function_name
41
41
  attributes << context if context
42
42
 
43
43
  <<-SQL.gsub(/^ {6}/, '')
@@ -46,4 +46,4 @@ module Dumbo
46
46
  SQL
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -1,6 +1,6 @@
1
1
  module Dumbo
2
2
  class CompositeType < Type
3
- attr_accessor :attributes
3
+ attr_accessor :attributes
4
4
 
5
5
  def load_attributes
6
6
  super
@@ -16,11 +16,11 @@ module Dumbo
16
16
  SQL
17
17
 
18
18
  attribute = Struct.new(:name, :type)
19
- @attributes = res.map{|r| attribute.new(r['attname'],r['typname'])}
19
+ @attributes = res.map { |r| attribute.new(r['attname'], r['typname']) }
20
20
  end
21
21
 
22
22
  def to_sql
23
- attr_str = attributes.map{|a| "#{a.name} #{a.type}"}.join(",\n ")
23
+ attr_str = attributes.map { |a| "#{a.name} #{a.type}" }.join(",\n ")
24
24
  <<-SQL.gsub(/^ {6}/, '')
25
25
  CREATE TYPE #{name} AS (
26
26
  #{attr_str}
@@ -28,4 +28,4 @@ module Dumbo
28
28
  SQL
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -1,6 +1,7 @@
1
- require "rake"
1
+ require 'rake'
2
2
  require 'rake/tasklib'
3
3
  require 'active_record'
4
+ require 'yaml'
4
5
 
5
6
  module Dumbo
6
7
  class DbTask < ::Rake::TaskLib
@@ -9,7 +10,7 @@ module Dumbo
9
10
  @name = name
10
11
 
11
12
  namespace name do
12
- task environment: ['db:configure_connection' ]
13
+ task environment: ['db:configure_connection']
13
14
 
14
15
  task :configuration do
15
16
  @config = YAML.load_file('config/database.yml')[ENV['DUMBO_ENV']]
@@ -33,16 +34,16 @@ module Dumbo
33
34
 
34
35
  namespace :test do
35
36
  task :environment do
36
- ENV['DUMBO_ENV'] ||= 'test'
37
+ ENV['DUMBO_ENV'] = 'test'
37
38
  ActiveRecord::Schema.verbose = false
38
39
  end
39
40
 
40
41
  task load_structure: :environment do
41
- filename = ENV['DB_STRUCTURE'] || File.join("db", "structure.sql")
42
+ filename = ENV['DB_STRUCTURE'] || File.join('db', 'structure.sql')
42
43
  ActiveRecord::Tasks::DatabaseTasks.structure_load(@config, filename)
43
44
  end
44
45
 
45
- desc "Re-create and prepare test database"
46
+ desc 'Re-create and prepare test database'
46
47
  task prepare: [:environment, :drop, :create]
47
48
  end
48
49
  end
@@ -2,7 +2,6 @@ require 'pathname'
2
2
  require 'active_support/core_ext/module/attribute_accessors'
3
3
 
4
4
  module Dumbo
5
-
6
5
  class DependencyNotFound < StandardError
7
6
  attr_accessor :dep, :file
8
7
 
@@ -23,7 +22,7 @@ module Dumbo
23
22
  end
24
23
 
25
24
  def resolve
26
- list = dependency_list.sort{|a,b| a.last.size <=> b.last.size}
25
+ list = dependency_list.sort { |a, b| a.last.size <=> b.last.size }
27
26
  resolve_list(list)
28
27
  end
29
28
 
@@ -33,14 +32,13 @@ module Dumbo
33
32
  @resolve_list = []
34
33
  @temp_list = list
35
34
  loops = 0
36
- until @temp_list.empty? || loops > 10 do
37
- @temp_list.each do |(file, deps)|
38
- _resolve(file, deps)
39
- end
40
- loops +=1
35
+ # TODO find a better way here
36
+ until @temp_list.empty? || loops * 10 > @temp_list.size
37
+ file, deps = @temp_list.first
38
+ loops += 1 unless _resolve(file, deps)
41
39
  end
42
40
 
43
- raise "Can't resolve dependencies" if loops > 10
41
+ fail "Can't resolve dependencies" if loops > 10
44
42
 
45
43
  @resolve_list
46
44
  end
@@ -48,26 +46,26 @@ module Dumbo
48
46
  def _resolve(file, deps)
49
47
  if deps.empty?
50
48
  @resolve_list.push(@temp_list.shift.first)
51
- return
49
+ return true
52
50
  end
53
51
 
54
52
  left = deps - @resolve_list
55
53
  if left.empty?
56
54
  @resolve_list.push(@temp_list.shift.first)
57
- return
55
+ return true
58
56
  else
59
57
  @temp_list.push @temp_list.shift
58
+ return false
60
59
  end
61
60
  end
62
61
 
63
-
64
62
  def dependency_list
65
63
  @file_list.map do |file|
66
64
  deps = []
67
65
  IO.foreach(file) do |line|
68
66
  catch(:done) do
69
67
  dep = parse(line)
70
- deps << relative_path(dep,file) if dep
68
+ deps << relative_path(dep, file) if dep
71
69
  end
72
70
  end
73
71
  [file, deps]
@@ -76,30 +74,31 @@ module Dumbo
76
74
 
77
75
  def encoded_line(line)
78
76
  if String.method_defined?(:encode)
79
- line.encode!('UTF-8', 'UTF-8', :invalid => :replace)
77
+ line.encode!('UTF-8', 'UTF-8', invalid: :replace)
80
78
  else
81
79
  line
82
80
  end
83
81
  end
84
82
 
85
83
  def parse(line)
86
- return $1 if encoded_line(line) =~ DependencyResolver.depends_pattern
84
+ return Regexp.last_match[1] if encoded_line(line) =~ DependencyResolver.depends_pattern
87
85
 
88
86
  # end of first commenting block we're done.
89
87
  throw :done unless line =~ /--/
90
88
  end
91
89
 
92
- def relative_path(dep,file)
90
+ def relative_path(dep, file)
93
91
  p = Pathname.new(file).dirname.join(dep)
94
92
  if p.exist? && p.extname.present?
95
93
  return p.to_s
96
94
  elsif p.extname.empty?
97
- %w(.sql .erb).each do |ext|
95
+ %w(.sql .erb .sql.erb).each do |ext|
98
96
  new_p = p.sub_ext(ext)
99
97
  return new_p.to_s if new_p.exist?
100
98
  end
101
99
  end
102
- raise DependencyNotFound.new(dep, file)
100
+
101
+ fail DependencyNotFound.new(dep, file)
103
102
  end
104
103
  end
105
- end
104
+ end