Class: DbAgile::Core::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/dbagile/core/database.rb

Overview

Encapsulates a database handler.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, uri = nil, &block) ⇒ Database

Creates a database instance

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
# File 'lib/dbagile/core/database.rb', line 29

def initialize(name, uri = nil, &block)
  raise ArgumentError, "Database name is mandatory" unless name.kind_of?(Symbol)
  raise ArgumentError, "Database DSL is deprecated" unless block.nil?
  @name = name
  @uri = uri
  @announced_files = []
  @effective_files = []
  @file_resolver = lambda{|f| ::File.expand_path(f) }
  @chain = ::DbAgile::Core::Chain.new
end

Instance Attribute Details

#announced_filesObject

Array of files for the announced schema



15
16
17
# File 'lib/dbagile/core/database.rb', line 15

def announced_files
  @announced_files
end

#effective_filesObject

Array of files for the effective schema



19
20
21
# File 'lib/dbagile/core/database.rb', line 19

def effective_files
  @effective_files
end

#file_resolverObject

Resolves relative files



23
24
25
# File 'lib/dbagile/core/database.rb', line 23

def file_resolver
  @file_resolver
end

#nameObject (readonly)

Database name



9
10
11
# File 'lib/dbagile/core/database.rb', line 9

def name
  @name
end

#plugsObject (readonly)

Plugs as arrays of arrays



26
27
28
# File 'lib/dbagile/core/database.rb', line 26

def plugs
  @plugs
end

#uriObject

Database uri



12
13
14
# File 'lib/dbagile/core/database.rb', line 12

def uri
  @uri
end

Instance Method Details

#announced_schema(unstage = false) ⇒ Object

Returns the announced schema. If no announce schema files are installed and unstage is true, returns the effective schema. Returns nil otherwise.



133
134
135
136
137
138
139
140
141
# File 'lib/dbagile/core/database.rb', line 133

def announced_schema(unstage = false)
  if has_announced_schema?
    load_schema_from_files(announced_files)
  elsif unstage
    effective_schema(unstage)
  else
    nil
  end
end

#connect(options = {}) ⇒ Object

Connects and returns a Connection object

Raises:

  • (ArgumentError)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/dbagile/core/database.rb', line 69

def connect(options = {})
  raise ArgumentError, "Options should be a Hash" unless options.kind_of?(Hash)
  raise DbAgile::Error, "Database has no uri" if uri.nil?
  if uri =~ /:\/\//
    adapter = DbAgile::Adapter::factor(uri, options)
  elsif file_resolver
    file = file_resolver.call(uri)
    adapter = DbAgile::Adapter::factor("sqlite://#{file}", options)
  else
    raise DbAgile::Error, "A file resolver is required for using #{uri} as database uri"
  end
  connector = @chain.connect(adapter)
  Connection.new(connector)
end

#effective_schema(unstage = false) ⇒ Object

Returns the effective schema. If no effective files are installed and unstage is true, returns the physical schema. Returns nil otherwise.



162
163
164
165
166
167
168
169
170
# File 'lib/dbagile/core/database.rb', line 162

def effective_schema(unstage = false)
  if has_effective_schema?
    load_schema_from_files(effective_files)
  elsif unstage
    physical_schema
  else
    nil
  end
end

#has_announced_schema?Boolean

Does this database has announced schema files?

Returns:

  • (Boolean)


106
107
108
# File 'lib/dbagile/core/database.rb', line 106

def has_announced_schema?
  !(@announced_files.nil? or @announced_files.empty?)
end

#has_effective_schema?Boolean

Does this database has effective schema files?

Returns:

  • (Boolean)


111
112
113
# File 'lib/dbagile/core/database.rb', line 111

def has_effective_schema?
  !(@effective_files.nil? or @effective_files.empty?)
end

#physical_schemaObject

Returns the database physical schema



190
191
192
# File 'lib/dbagile/core/database.rb', line 190

def physical_schema
  with_connection{|c| c.physical_schema}
end

#ping?Boolean

Checks if the connection pings correctly.

Returns:

  • (Boolean)


64
65
66
# File 'lib/dbagile/core/database.rb', line 64

def ping?
  connect.ping?
end

#plug(*args) ⇒ Object

See Also:



47
48
49
50
# File 'lib/dbagile/core/database.rb', line 47

def plug(*args)
  (@plugs ||= []).push(*args)
  @chain.plug(*args)
end

#plugins=(plugins) ⇒ Object

Installs plugins



53
54
55
56
# File 'lib/dbagile/core/database.rb', line 53

def plugins=(plugins)
  plugins = plugins.collect{|p| Kernel.eval(p)}
  plug(*plugins)
end

#schemaObject

Returns the schema of highest level (announced -> effective -> physical).



127
128
129
# File 'lib/dbagile/core/database.rb', line 127

def schema
  announced_schema(true)
end

#set_announced_schema(schema) ⇒ Object

Overrides announced schema with a given schema



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/dbagile/core/database.rb', line 144

def set_announced_schema(schema)
  # Set announced files
  self.announced_files ||= []
  case announced_files.size
    when 0
      FileUtils.mkdir_p(file_resolver.call(name))
      self.announced_files = [ "#{name}/announced.yaml" ]
    when 1
    else 
      raise "Unable to set announced schema with multiple effective files"
  end
  ::File.open(file_resolver.call(announced_files[0]), 'w') do |io|
    io << schema.to_yaml
  end
end

#set_effective_schema(schema) ⇒ Object

Overrides effective schema with a given schema



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/dbagile/core/database.rb', line 173

def set_effective_schema(schema)
  # Set effective files
  self.effective_files ||= []
  case effective_files.size
    when 0
      FileUtils.mkdir_p(file_resolver.call(name.to_s))
      self.effective_files = [ "#{name}/effective.yaml" ]
    when 1
    else 
      raise "Unable to set effective schema with multiple effective files"
  end
  ::File.open(file_resolver.call(effective_files[0]), 'w') do |io|
    io << schema.to_yaml
  end
end

#to_yaml(opts = {}) ⇒ Object

Converts this database to a yaml string



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/dbagile/core/database.rb', line 201

def to_yaml(opts = {})
  YAML::quick_emit(self, opts){|out|
    out.map("tag:yaml.org,2002:map") do |map|
      map.add('uri', self.uri)
      if has_announced_schema?
        map.add('announced_schema', self.announced_files || [])
      end
      if has_effective_schema?
        map.add('effective_schema', self.effective_files || [])
      end
      if plugs and not(plugs.empty?) 
        ps = plugs.collect{|p| SByC::TypeSystem::Ruby::to_literal(p)}
        map.add('plugins', ps)
      end
    end
  }
end

#with_connection(conn_options = {}) ⇒ Object

Yields the block with a connection; disconnect after that.

Returns:

  • block execution result

Raises:

  • ArgumentError if no block is provided



90
91
92
93
94
95
96
97
98
99
# File 'lib/dbagile/core/database.rb', line 90

def with_connection(conn_options = {})
  raise ArgumentError, "Missing block" unless block_given?
  begin
    connection = connect(conn_options)
    result = yield(connection)
    result
  ensure
    connection.disconnect if connection
  end
end