Class: Sequel::Fixture

Inherits:
Object
  • Object
show all
Defined in:
lib/sequel-fixture.rb,
lib/sequel-fixture/util.rb,
lib/sequel-fixture/table.rb,
lib/sequel-fixture/version.rb,
lib/sequel-fixture/exceptions.rb

Defined Under Namespace

Classes: ChangingConnectionIllegal, DatabaseError, IllegalFixtureFormat, LoadingFixtureIllegal, MissingConnectionError, MissingFixtureError, MissingProcessedValueError, RollbackIllegalError, Row, Table, TablesNotEmptyError

Constant Summary collapse

VERSION =
"2.0.4"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fixture = nil, connection = nil, option_push = true) ⇒ Fixture

Description

Initializes the fixture handler Accepts optionally a symbol as a reference to the fixture and a Sequel::Database connection



32
33
34
35
36
37
38
39
40
# File 'lib/sequel-fixture.rb', line 32

def initialize(fixture = nil, connection = nil, option_push = true)
  @schema = {}
  @data = {}

  load(fixture) if fixture

  @connection = connection if connection
  push if fixture && connection && option_push
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(key, *args) ⇒ Object

Description

For enabling discovery of tables



74
75
76
77
# File 'lib/sequel-fixture.rb', line 74

def method_missing(key, *args)
  return @data[key] if @data && @data.has_key?(key)
  return super
end

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



190
191
192
# File 'lib/sequel-fixture.rb', line 190

def connection
  @connection
end

#dataObject (readonly)

Returns the value of attribute data.



191
192
193
# File 'lib/sequel-fixture.rb', line 191

def data
  @data
end

#schemaObject (readonly)

Returns the value of attribute schema.



192
193
194
# File 'lib/sequel-fixture.rb', line 192

def schema
  @schema
end

Class Method Details

.pathObject

Description

Returns the current path to the fixtures folder



16
17
18
# File 'lib/sequel-fixture.rb', line 16

def self.path
  @@path ||= "test/fixtures"
end

.path=(path) ⇒ Object

Description

Set the current path of the fixtures folder



24
25
26
# File 'lib/sequel-fixture.rb', line 24

def self.path=(path)
  @@path = path
end

Instance Method Details

#[](reference) ⇒ Object

Description

Returns the SymbolMatrix with the data referring to that table



82
83
84
# File 'lib/sequel-fixture.rb', line 82

def [](reference)
  @data[reference]
end

#checkObject

Description

Assures that the tables are empty before proceeding



98
99
100
101
102
103
104
105
# File 'lib/sequel-fixture.rb', line 98

def check
  return @checked if @checked # If already checked, it's alright

  raise MissingFixtureError, "No fixture has been loaded, nothing to check" unless @data.length > 0
  raise MissingConnectionError, "No connection has been provided, impossible to check" unless @connection

  return @checked = true
end

#fixtures_pathObject

Description

Returns the current fixtures path where Sequel::Fixture looks for fixture folders



66
67
68
# File 'lib/sequel-fixture.rb', line 66

def fixtures_path
  Sequel::Fixture.path
end

#force_checked!Object

Description

Forces the check to pass. Dangerous!



90
91
92
# File 'lib/sequel-fixture.rb', line 90

def force_checked!
  @checked = true
end

#load(fixture) ⇒ Object

Description

Loads the fixture files into this instance



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/sequel-fixture.rb', line 46

def load(fixture)
  raise LoadingFixtureIllegal, "A check has already been made, loading a different fixture is illegal" if @checked

  Dir.entries("#{fixtures_path}/#{fixture}").reject {|f| f =~ /^\./} .each do |file|
    key = file.split('.').first.to_sym
    @data ||= {}
    @schema ||= {}

    file_data = SymbolMatrix.new "#{fixtures_path}/#{fixture}/#{file}"

    if file_data
      @data[key] = Table.new(file_data[:data]) if file_data.key?(:data)
      @schema[key] = file_data[:schema] if file_data.key?(:schema)
    end
  end
end

#pushObject

Description

Initializes fixture schema and Inserts the fixture data into the corresponding tables



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/sequel-fixture.rb', line 112

def push
  check

  @schema.each do |table, matrix|
    push_schema(table, matrix)
  end

  @data.each do |table_name, table_data|
    table_data.rows.each do |values|
      begin
        @connection[table_name].insert(simplify(values.to_h))
      rescue MissingProcessedValueError => m
        rollback
        raise MissingProcessedValueError, "In record '#{values.to_h}' to be inserted into '#{table_name}', the processed value of field '#{m.field}' is missing, aborting."
      rescue NoMethodError => e
        raise IllegalFixtureFormat, "In record '#{values}', data must be formatted as arrays of hashes. Check 'data' section in '#{table_name}.yaml'"
      rescue Sequel::DatabaseError => sde
        raise Sequel::Fixture::DatabaseError, "DB table: #{table_name}, #{sde.message}"
      end
    end
  end
end

#push_schema(table, values) ⇒ Object

Description

Create the schema in our DB connection based on the schema values



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/sequel-fixture.rb', line 139

def push_schema(table, values)
  ## Lets passively ignore the schema if the table already exists
  return if @connection.table_exists?(table.to_sym)

  ## Find the primary key
  pkey_data = nil
  values.each do |column_def|
    pkey_data = column_def if column_def["primary_key"]
  end

  ## Create the table with the primary key
  @connection.create_table(table) do
    column(pkey_data["name"].to_sym, pkey_data["type"].to_sym)
  end

  ## Add the rest of the columns
  values.each do |column_def|
    unless column_def["primary_key"]
      @connection.alter_table(table) { add_column(column_def["name"].to_sym, column_def["type"].to_sym) }
    end
  end
end

#rollbackObject

Description

Empties the tables, only if they were empty to begin with



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/sequel-fixture.rb', line 166

def rollback
  begin
    check

    @data.each_key do |table|
      @connection[table].truncate
    end
  rescue TablesNotEmptyError => e
    raise RollbackIllegalError, "The tables weren't empty to begin with, rollback aborted."
  end
end

#simplify(the_hash) ⇒ Object

Description

Simplifies the hash in order to insert it into the database (Note: I’m well aware that this functionality belongs in a dependency)



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/sequel-fixture/util.rb', line 7

def simplify(the_hash)    
  the_returned_hash = {}
  
  the_hash.each do |key, value|
    if value.is_a? Hash
      unless value.has_key?("processed") || value.has_key?(:processed)
        raise MissingProcessedValueError.new "The processed value to insert into the db is missing from the field '#{key}', aborting", key 
      end
      the_returned_hash[key] = value["processed"] || value[:processed]
    else
      the_returned_hash[key] = value
    end
  end
  return the_returned_hash
end