dbagile 0.0.1 → 0.0.2

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 (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