dbagile 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/lib/dbagile.rb +2 -2
  2. data/lib/dbagile/adapter/sequel/data/transaction_driven.rb +1 -0
  3. data/lib/dbagile/adapter/sequel/schema/concrete_script.rb +18 -0
  4. data/lib/dbagile/adapter/sequel/schema/table_driven.rb +10 -1
  5. data/lib/dbagile/adapter/sequel/sequel_tracer.rb +1 -0
  6. data/lib/dbagile/command/bulk/commons.rb +7 -2
  7. data/lib/dbagile/command/bulk/export.rb +4 -1
  8. data/lib/dbagile/command/bulk/import.rb +32 -2
  9. data/lib/dbagile/command/schema/check.rb +2 -1
  10. data/lib/dbagile/command/schema/commons.rb +16 -1
  11. data/lib/dbagile/command/schema/dump.rb +85 -4
  12. data/lib/dbagile/command/schema/sql_script.rb +1 -0
  13. data/lib/dbagile/contract/data/dataset.rb +9 -0
  14. data/lib/dbagile/core/schema/builder.rb +8 -4
  15. data/lib/dbagile/core/schema/builder/concept_factory.rb +5 -0
  16. data/lib/dbagile/core/schema/composite.rb +1 -1
  17. data/lib/dbagile/core/schema/computations/merge.rb +1 -1
  18. data/lib/dbagile/core/schema/errors.rb +1 -3
  19. data/lib/dbagile/core/schema/logical.rb +1 -0
  20. data/lib/dbagile/core/schema/logical/attribute.rb +11 -2
  21. data/lib/dbagile/core/schema/logical/relview.rb +42 -0
  22. data/lib/dbagile/core/schema/migrate/abstract_script.rb +2 -0
  23. data/lib/dbagile/core/schema/migrate/create_view.rb +15 -0
  24. data/lib/dbagile/core/schema/migrate/drop_view.rb +15 -0
  25. data/lib/dbagile/core/schema/migrate/operation.rb +8 -6
  26. data/lib/dbagile/core/schema/migrate/stager.rb +12 -3
  27. data/lib/dbagile/core/schema/part.rb +0 -49
  28. data/lib/dbagile/core/schema/schema_object.rb +54 -0
  29. data/lib/dbagile/environment/repository.rb +2 -2
  30. data/lib/dbagile/errors.rb +3 -0
  31. data/lib/dbagile/io.rb +7 -3
  32. data/lib/dbagile/io/html.rb +48 -0
  33. data/lib/dbagile/restful.rb +1 -1
  34. data/lib/dbagile/restful/middleware/one_database.rb +1 -0
  35. data/lib/dbagile/restful/middleware/post.rb +16 -1
  36. data/lib/dbagile/tools/tuple.rb +7 -0
  37. data/test/assumptions/sequel/connect.spec +12 -9
  38. data/test/assumptions/sequel/test.db +0 -0
  39. data/test/commands.spec +4 -4
  40. data/test/commands/bulk/import.spec +26 -3
  41. data/test/commands/schema/check.spec +20 -13
  42. data/test/commands/schema/dump.spec +23 -0
  43. data/test/fixtures/basics/dbagile.idx +7 -7
  44. data/test/fixtures/basics/robust.db +0 -0
  45. data/test/fixtures/basics/test.db +0 -0
  46. data/test/fixtures/empty/dbagile.idx +1 -1
  47. data/test/restful/get/html_format.ex +12 -0
  48. data/test/run_all_suite.rb +1 -1
  49. data/test/spec_helper.rb +0 -2
  50. data/test/support/be_a_valid_json_string.rb +1 -1
  51. data/test/support/be_a_valid_yaml_string.rb +1 -1
  52. data/test/unit/core/schema/fixtures/views.yaml +5 -0
  53. data/test/unit/core/schema/part_keys.spec +12 -0
  54. data/test/unit/core/schema/yaml_load.spec +5 -0
  55. metadata +414 -244
@@ -102,13 +102,11 @@ module DbAgile
102
102
  TargetKeyMismatch
103
103
  ]
104
104
  MESSAGE_VALUES = [
105
- 'invalid default value on attribute #{schema_object.name}',
105
+ 'invalid default value \'#{schema_object.default_value}\' on #{schema_object}',
106
106
  'relvar #{schema_object.relation_variable.name} has an empty heading (unsupported so far)',
107
107
  'relvar #{schema_object.name} has no primary key',
108
108
  'invalid constraint #{schema_object.name} on #{schema_object.relation_variable.name}',
109
-
110
109
  'invalid index #{schema_object.name}',
111
-
112
110
  'no such relvar #{args[:relvar_name]}',
113
111
  'no such attributes #{args[:attributes].join(\',\')}',
114
112
  'no such candidate key #{args[:constraint_name]}',
@@ -18,6 +18,7 @@ module DbAgile
18
18
  end # module Core
19
19
  end # module DbAgile
20
20
  require 'dbagile/core/schema/logical/relvar'
21
+ require 'dbagile/core/schema/logical/relview'
21
22
  require 'dbagile/core/schema/logical/heading'
22
23
  require 'dbagile/core/schema/logical/attribute'
23
24
  require 'dbagile/core/schema/logical/constraints'
@@ -22,6 +22,10 @@ module DbAgile
22
22
  def mandatory?
23
23
  !(definition[:mandatory] == false)
24
24
  end
25
+
26
+ def relvar
27
+ parent.parent
28
+ end
25
29
 
26
30
  ############################################################################
27
31
  ### Dependency control
@@ -38,7 +42,7 @@ module DbAgile
38
42
 
39
43
  # @see DbAgile::Core::Schema::SchemaObject
40
44
  def _semantics_check(clazz, buffer)
41
- unless default_value.nil? or default_value.kind_of?(domain)
45
+ unless default_value.nil? or (domain === default_value)
42
46
  buffer.add_error(self, clazz::InvalidDefaultValue)
43
47
  end
44
48
  end
@@ -54,13 +58,18 @@ module DbAgile
54
58
  out.map("tag:yaml.org,2002:map", :inline ) do |map|
55
59
  map.add('domain', defn[:domain].to_s)
56
60
  map.add('mandatory', false) unless defn[:mandatory]
57
- if defn[:default]
61
+ unless defn[:default].nil?
58
62
  map.add('default', defn[:default])
59
63
  end
60
64
  end
61
65
  }
62
66
  end
63
67
 
68
+ # Returns a string representation
69
+ def to_s
70
+ "Attribute #{relvar.name}::#{name} #{definition.inspect}"
71
+ end
72
+
64
73
  end # class Attribute
65
74
  end # module Logical
66
75
  end # module Schema
@@ -0,0 +1,42 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ class Logical
5
+ class Relview < Schema::Part
6
+
7
+ ############################################################################
8
+ ### Dependency control
9
+ ############################################################################
10
+
11
+ # @see DbAgile::Core::Schema::SchemaObject
12
+ def dependencies(include_parent = false)
13
+ include_parent ? [ parent ] : []
14
+ end
15
+
16
+ ############################################################################
17
+ ### Check interface
18
+ ############################################################################
19
+
20
+ # @see DbAgile::Core::Schema::SchemaObject
21
+ def _semantics_check(clazz, buffer)
22
+ end
23
+
24
+ ############################################################################
25
+ ### About IO
26
+ ############################################################################
27
+
28
+ # Delegation pattern on YAML flushing
29
+ def to_yaml(opts = {})
30
+ definition.to_yaml(opts)
31
+ end
32
+
33
+ # Returns a string representation
34
+ def to_s
35
+ "Relview #{name} #{definition.inspect}"
36
+ end
37
+
38
+ end # class Relview
39
+ end # module Logical
40
+ end # module Schema
41
+ end # module Core
42
+ end # module DbAgile
@@ -33,3 +33,5 @@ require 'dbagile/core/schema/migrate/create_table'
33
33
  require 'dbagile/core/schema/migrate/drop_table'
34
34
  require 'dbagile/core/schema/migrate/expand_table'
35
35
  require 'dbagile/core/schema/migrate/collapse_table'
36
+ require 'dbagile/core/schema/migrate/create_view'
37
+ require 'dbagile/core/schema/migrate/drop_view'
@@ -0,0 +1,15 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ module Migrate
5
+ class CreateView < Migrate::Operation
6
+
7
+ def to_sql92
8
+ "CREATE VIEW #{table_name} (#{relvar.definition})"
9
+ end
10
+
11
+ end # class CreateView
12
+ end # module Migrate
13
+ end # module Schema
14
+ end # module Core
15
+ end # module DbAgile
@@ -0,0 +1,15 @@
1
+ module DbAgile
2
+ module Core
3
+ module Schema
4
+ module Migrate
5
+ class DropView < Migrate::Operation
6
+
7
+ def to_sql92
8
+ "DROP VIEW #{table_name}"
9
+ end
10
+
11
+ end # class DropView
12
+ end # module Migrate
13
+ end # module Schema
14
+ end # module Core
15
+ end # module DbAgile
@@ -7,19 +7,21 @@ module DbAgile
7
7
  # The sub operations
8
8
  attr_reader :operations
9
9
 
10
- # Targetted relation variable
11
- attr_reader :relvar
10
+ # Targetted relation variable/view
11
+ attr_reader :rel_object
12
+ alias :relvar :rel_object
13
+ alias :relview :rel_object
12
14
 
13
15
  # Returns table name
14
16
  def table_name
15
17
  relvar.name
16
18
  end
17
19
 
18
- def initialize(relvar)
19
- unless relvar.kind_of?(DbAgile::Core::Schema::Logical::Relvar)
20
- raise ArgumentError, "Relvar expected for relvar, got #{relvar.class}"
20
+ def initialize(rel_object)
21
+ unless rel_object.relvar? or rel_object.relview?
22
+ raise ArgumentError, "Relvar expected for rel_object, got #{rel_object.class}"
21
23
  end
22
- @relvar = relvar
24
+ @rel_object = rel_object
23
25
  @operations = []
24
26
  end
25
27
 
@@ -139,6 +139,11 @@ module DbAgile
139
139
  script << Migrate::DropTable.new(relvar)
140
140
  end
141
141
 
142
+ # Collapses a relation view
143
+ def collapse_relview(relview)
144
+ script << Migrate::DropView.new(relview)
145
+ end
146
+
142
147
  # Collapses a candidate key
143
148
  def collapse_candidate_key(ckey)
144
149
  with_collapse_helper(ckey.relation_variable){|h| h.candidate_key(ckey)}
@@ -172,16 +177,16 @@ module DbAgile
172
177
  # create the operation
173
178
  exists = relvar_exists?(rv)
174
179
  h = exists ? Migrate::ExpandTable.new(rv) : Migrate::CreateTable.new(rv)
175
-
180
+
176
181
  # execute sub operations and save
177
182
  yield(helpers[rv] = h)
178
183
  script << h
179
-
184
+
180
185
  # assert that the table now exists
181
186
  unless exists
182
187
  relvar_exists!(rv)
183
188
  end
184
-
189
+
185
190
  # remove helper now
186
191
  helpers.delete(rv)
187
192
  end
@@ -248,6 +253,10 @@ module DbAgile
248
253
  end
249
254
  alias :expand_relvar :expand_relvar_xxx
250
255
  alias :expand_heading :expand_relvar_xxx
256
+
257
+ def expand_relview(rv)
258
+ script << Migrate::CreateView.new(rv)
259
+ end
251
260
 
252
261
  ### Parts
253
262
 
@@ -25,55 +25,6 @@ module DbAgile
25
25
  def _semantics_check(clazz, buffer)
26
26
  end
27
27
 
28
- ############################################################################
29
- ### Schema typing
30
- ############################################################################
31
-
32
- # Returns true if this object is a logical object, false otherwise
33
- def logical?
34
- relvar? or attribute? or constraint?
35
- end
36
-
37
- # Returns true if this object is a relation variable, false otherwise
38
- def relvar?
39
- self.kind_of?(Schema::Logical::Relvar)
40
- end
41
-
42
- # Returns true if this object is an attribute, false otherwise
43
- def attribute?
44
- self.kind_of?(Schema::Logical::Attribute)
45
- end
46
-
47
- # Returns true if this object is a constraint, false otherwise
48
- def constraint?
49
- self.kind_of?(Schema::Logical::Constraint)
50
- end
51
-
52
- # Returns true if this object is a candidate key, false otherwise
53
- def candidate_key?
54
- self.kind_of?(Schema::Logical::Constraint::CandidateKey)
55
- end
56
-
57
- # Returns true if this object is a primary key, false otherwise
58
- def primary_key?
59
- self.candidate_key? and self.primary?
60
- end
61
-
62
- # Returns true if this object is a foreign key, false otherwise
63
- def foreign_key?
64
- self.kind_of?(Schema::Logical::Constraint::ForeignKey)
65
- end
66
-
67
- # Returns true if this object is a physical object, false otherwise
68
- def physical?
69
- index?
70
- end
71
-
72
- # Returns true if this object is an index, false otherwise
73
- def index?
74
- self.kind_of?(Schema::Physical::Index)
75
- end
76
-
77
28
  ############################################################################
78
29
  ### Schema::SchemaObject
79
30
  ############################################################################
@@ -25,6 +25,60 @@ module DbAgile
25
25
  end
26
26
  alias :terminal? :part?
27
27
 
28
+ ############################################################################
29
+ ### Schema typing
30
+ ############################################################################
31
+
32
+ # Returns true if this object is a logical object, false otherwise
33
+ def logical?
34
+ relvar? or relview? or attribute? or constraint?
35
+ end
36
+
37
+ # Returns true if this object is a relation view, false otherwise
38
+ def relview?
39
+ self.kind_of?(Schema::Logical::Relview)
40
+ end
41
+
42
+ # Returns true if this object is a relation variable, false otherwise
43
+ def relvar?
44
+ self.kind_of?(Schema::Logical::Relvar)
45
+ end
46
+
47
+ # Returns true if this object is an attribute, false otherwise
48
+ def attribute?
49
+ self.kind_of?(Schema::Logical::Attribute)
50
+ end
51
+
52
+ # Returns true if this object is a constraint, false otherwise
53
+ def constraint?
54
+ self.kind_of?(Schema::Logical::Constraint)
55
+ end
56
+
57
+ # Returns true if this object is a candidate key, false otherwise
58
+ def candidate_key?
59
+ self.kind_of?(Schema::Logical::CandidateKey)
60
+ end
61
+
62
+ # Returns true if this object is a primary key, false otherwise
63
+ def primary_key?
64
+ self.candidate_key? and self.primary?
65
+ end
66
+
67
+ # Returns true if this object is a foreign key, false otherwise
68
+ def foreign_key?
69
+ self.kind_of?(Schema::Logical::ForeignKey)
70
+ end
71
+
72
+ # Returns true if this object is a physical object, false otherwise
73
+ def physical?
74
+ index?
75
+ end
76
+
77
+ # Returns true if this object is an index, false otherwise
78
+ def index?
79
+ self.kind_of?(Schema::Physical::Index)
80
+ end
81
+
28
82
  ############################################################################
29
83
  ### Schema hierarchy
30
84
  ############################################################################
@@ -118,7 +118,7 @@ module DbAgile
118
118
  def with_current_database
119
119
  raise ArgumentError, "Missing block" unless block_given?
120
120
  db = repository.current_database
121
- raise NoDefaultDatabaseError if db.nil?
121
+ raise DbAgile::NoDefaultDatabaseError, "No default database set (try 'dba use ...' first)" if db.nil?
122
122
  yield(db)
123
123
  end
124
124
 
@@ -140,7 +140,7 @@ module DbAgile
140
140
  raise ArgumentError, "Invalid database name #{db}"
141
141
  end
142
142
  raise NoSuchDatabaseError if db.nil?
143
- db.with_connection(&block)
143
+ db.with_connection(conn_options, &block)
144
144
  end
145
145
 
146
146
  #
@@ -27,4 +27,7 @@ module DbAgile
27
27
  # Raised when usage of schema files fails because they are not installed
28
28
  class NoSchemaFilesError < DbAgile::Error; end
29
29
 
30
+ # Raised when a candidate key cannot be infered from a given tuple
31
+ class CandidateKeyNotFoundError < DbAgile::Error; end
32
+
30
33
  end # module DbAgile
@@ -4,6 +4,7 @@ require 'dbagile/io/csv'
4
4
  require 'dbagile/io/json'
5
5
  require 'dbagile/io/yaml'
6
6
  require 'dbagile/io/xml'
7
+ require 'dbagile/io/html'
7
8
  require 'dbagile/io/ruby'
8
9
  require 'dbagile/io/text'
9
10
  module DbAgile
@@ -15,10 +16,10 @@ module DbAgile
15
16
  }
16
17
 
17
18
  # Known IO formats
18
- KNOWN_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml]
19
+ KNOWN_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml, :html]
19
20
 
20
21
  # Known to_xxx IO formats
21
- KNOWN_TO_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml]
22
+ KNOWN_TO_FORMATS = [:yaml, :csv, :json, :ruby, :text, :xml, :html]
22
23
 
23
24
  # Known from_xxx formats
24
25
  KNOWN_FROM_FORMATS = [:yaml, :csv, :json, :ruby]
@@ -30,7 +31,8 @@ module DbAgile
30
31
  :json => DbAgile::IO::JSON,
31
32
  :ruby => DbAgile::IO::Ruby,
32
33
  :text => DbAgile::IO::Text,
33
- :xml => DbAgile::IO::XML
34
+ :xml => DbAgile::IO::XML,
35
+ :html => DbAgile::IO::HTML
34
36
  }
35
37
 
36
38
  # Which format for what extension
@@ -41,6 +43,7 @@ module DbAgile
41
43
  ".yaml" => :yaml,
42
44
  ".yml" => :yaml,
43
45
  ".xml" => :xml,
46
+ ".html" => :html,
44
47
  ".ruby" => :ruby,
45
48
  ".rb" => :ruby
46
49
  }
@@ -52,6 +55,7 @@ module DbAgile
52
55
  :json => "application/json",
53
56
  :yaml => "text/yaml",
54
57
  :xml => "text/xml",
58
+ :html => "text/html",
55
59
  :ruby => "text/plain"
56
60
  }
57
61
 
@@ -0,0 +1,48 @@
1
+ require "cgi"
2
+ module DbAgile
3
+ module IO
4
+ module HTML
5
+
6
+ DEFAULT_OPTIONS = { }
7
+
8
+ def with_tag(tag, buffer, indent = 0)
9
+ buffer << " "*indent << "<#{tag}>\n"
10
+ yield
11
+ buffer << " "*indent << "</#{tag}>\n"
12
+ end
13
+ module_function :with_tag
14
+
15
+ #
16
+ # Outputs some data as an HTML string
17
+ #
18
+ # @return [...] the buffer itself
19
+ #
20
+ def to_html(data, columns = nil, buffer = "", options = {})
21
+ options = DEFAULT_OPTIONS.merge(options)
22
+ with_tag("table", buffer, 0) {
23
+ with_tag("thead", buffer, 1) {
24
+ with_tag("tr", buffer, 2) {
25
+ columns.each{|column|
26
+ buffer << " "*3 << "<td>#{CGI::escape(column.to_s)}</td>\n"
27
+ }
28
+ }
29
+ }
30
+ with_tag("tbody", buffer, 1) {
31
+ data.each{|row|
32
+ with_tag("tr", buffer, 2) {
33
+ columns.each{|column|
34
+ value = row[column]
35
+ cssclazz = value.class.name.to_s.downcase
36
+ buffer << " "*3 << "<td class=\"#{cssclazz}\">#{CGI::escapeHTML(value.to_s)}</td>\n"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ buffer
43
+ end
44
+ module_function :to_html
45
+
46
+ end # module HTML
47
+ end # module IO
48
+ end # module DbAgile