Class: Taupe::Model::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/taupe/model/table.rb

Overview

Model table base class

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table, columns = nil, options = {}) ⇒ Table

Constructor

Parameters:

  • table (String)
  • columns (Hash) (defaults to: nil)
  • options (Hash) (defaults to: {})


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/taupe/model/table.rb', line 55

def initialize(table, columns = nil, options = {})
  columns = Taupe::Database.guess_schema(table) if columns.nil?

  @_table = table
  @_columns = columns
  @_pkey = nil
  @_pkey_id = options[:pkey_id] || nil
  @_cache_key = options[:cache_key] || nil
  @_values = options[:values] || {}

  # Clean up values (i.e SQLite duplicates values with numeric keys)
  @_values.each do |k, _v|
    @_values.delete(k) unless k.is_a? Symbol
  end

  @_pkey = columns.select { |_k, v| v[:primary_key] == true }.first[0]
  fail "Primary key undefined for model #{table}" if @_pkey.nil?

  if @_values.empty?
    return if @_pkey_id.nil?
    retrieve_from_database unless retrieve_from_cache
  else
    @_pkey_id = @_values[@_pkey] if @_pkey_id.nil?
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object

Method missing



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/taupe/model/table.rb', line 158

def method_missing(m, *args, &block)
  return @_pkey_id if m.to_sym == @_pkey.to_sym
  return @_values[m] if @_values.key? m

  ms = m.to_s
  if ms.include? '='
    ms = ms[0..-2]
    if @_columns.include? ms.to_sym
      @_values[ms.to_sym] = args[0]
      return true
    end
  end

  super
end

Class Attribute Details

._cache_keyObject

Returns the value of attribute _cache_key.



15
16
17
# File 'lib/taupe/model/table.rb', line 15

def _cache_key
  @_cache_key
end

._cnameObject

Returns the value of attribute _cname.



14
15
16
# File 'lib/taupe/model/table.rb', line 14

def _cname
  @_cname
end

._columnsObject

Returns the value of attribute _columns.



14
15
16
# File 'lib/taupe/model/table.rb', line 14

def _columns
  @_columns
end

._pkeyObject

Returns the value of attribute _pkey.



15
16
17
# File 'lib/taupe/model/table.rb', line 15

def _pkey
  @_pkey
end

._pkey_idObject

Returns the value of attribute _pkey_id.



15
16
17
# File 'lib/taupe/model/table.rb', line 15

def _pkey_id
  @_pkey_id
end

._tableObject

Returns the value of attribute _table.



14
15
16
# File 'lib/taupe/model/table.rb', line 14

def _table
  @_table
end

._valuesObject

Returns the value of attribute _values.



15
16
17
# File 'lib/taupe/model/table.rb', line 15

def _values
  @_values
end

Class Method Details

.exec(query) ⇒ Object

Execute a single query

Parameters:

  • query (String)

    The query to execute

Returns:

  • (Object)


201
202
203
# File 'lib/taupe/model/table.rb', line 201

def self.exec(query)
  Taupe::Database.exec query
end

.fetch(query, single = false) ⇒ Array, Object

Fetch objects from database

Parameters:

  • query (String)

    The query to fetch

  • single (Boolean) (defaults to: false)

    Must return one or more results?

Returns:

  • (Array, Object)


209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/taupe/model/table.rb', line 209

def self.fetch(query, single = false)
  results = []
  data = Taupe::Database.fetch(query)

  if data
    data.each do |h|
      results << load_from_hash(h)
    end
  end

  single ? results[0] : results
end

.load(pkey_id = nil, cache_key = nil) ⇒ Object

Load a new object

Parameters:

  • pkey_id (Numeric) (defaults to: nil)
  • cache_key (String) (defaults to: nil)


21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/taupe/model/table.rb', line 21

def self.load(pkey_id = nil, cache_key = nil)
  full_cname = "Taupe::Model::#{@_cname}"
  klass = full_cname.split('::').reduce(Object) { |a, e| a.const_get e }

  options = {
    pkey_id: pkey_id,
    cache_key: cache_key,
    values: nil
  }

  klass.new @_table, @_columns, options
end

.load_from_hash(values, pkey_id = nil, cache_key = nil) ⇒ Object

Load a new object from existing values

Parameters:

  • values (Hash)
  • pkey_id (Numeric) (defaults to: nil)
  • cache_key (String) (defaults to: nil)


38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/taupe/model/table.rb', line 38

def self.load_from_hash(values, pkey_id = nil, cache_key = nil)
  full_cname = "Taupe::Model::#{@_cname}"
  klass = full_cname.split('::').reduce(Object) { |a, e| a.const_get e }

  options = {
    pkey_id: pkey_id,
    cache_key: cache_key,
    values: values
  }

  klass.new @_table, @_columns, options
end

Instance Method Details

#add_property(key, value = nil, column_properties = {}) ⇒ Mixed

Add a propery to the current model

Parameters:

  • key (Symbol)
  • value (Mixed) (defaults to: nil)
  • column_properties (Hash) (defaults to: {})

Returns:

  • (Mixed)


186
187
188
189
190
191
192
193
194
195
196
# File 'lib/taupe/model/table.rb', line 186

def add_property(key, value = nil, column_properties = {})
  key = key.to_sym
  unless property? key
    @_values[key] = value

    # Include in database columns definition
    @_columns[key] = {} unless column_properties.empty?
  end

  @_values[key]
end

#deleteObject

Delete the model object



141
142
143
144
145
146
147
148
149
# File 'lib/taupe/model/table.rb', line 141

def delete
  fail 'Can not delete an unsaved model object' if @_pkey_id.nil?

  query = "DELETE FROM #{@_table} WHERE #{@_pkey} = #{@_pkey_id}"

  Taupe::Database.exec query

  Taupe::Cache.delete @_cache_key unless @_cache_key.nil?
end

#empty?Boolean

Is the object empty?

Returns:

  • (Boolean)


153
154
155
# File 'lib/taupe/model/table.rb', line 153

def empty?
  @_values.empty?
end

#property?(key) ⇒ Boolean

Check if current model has a given property

Parameters:

  • key (Symbol)

Returns:

  • (Boolean)


177
178
179
# File 'lib/taupe/model/table.rb', line 177

def property?(key)
  @_values.include? key.to_sym
end

#retrieve_from_cacheBoolean

Retrieve data from cache

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/taupe/model/table.rb', line 83

def retrieve_from_cache
  retrieved = false
  return retrieved if @_cache_key.nil?

  data = Taupe::Cache.get(@_cache_key) || nil
  unless data.nil? || data.empty?
    @_values = data
    retrieved = true
  end

  retrieved
end

#retrieve_from_databaseObject

Retrieve data from database



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/taupe/model/table.rb', line 97

def retrieve_from_database
  query = "SELECT * FROM #{@_table} WHERE #{@_pkey} = #{@_pkey_id}"
  result = Taupe::Database.fetch(query, true)

  return nil if result.nil? || result.empty?

  result.each do |k, v|
    @_values[k.to_sym] = v if k.is_a? Symbol
  end

  Taupe::Cache.set @_cache_key, @_values unless @_cache_key.nil?
end

#save(with_validations = true) ⇒ Object

Save the model object

Parameters:

  • with_validations (Boolean) (defaults to: true)


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/taupe/model/table.rb', line 112

def save(with_validations = true)
  Taupe::Validate.check(@_values, @_columns) if with_validations

  real_values = @_values.keep_if { |k, _v| @_columns.key?(k) }

  if @_pkey_id.nil?
    query = "
      INSERT INTO #{@_table}
         (#{real_values.keys.map(&:to_s).join(', ')})
      VALUES
         (#{real_values.values.map { |e| "'" + e.to_s + "'" }.join(', ')})
    "

    Taupe::Database.exec query
    @_pkey_id = Taupe::Database.last_id
  else
    joined_values = real_values.map { |k, v| "#{k} = '#{v}'" }.join(', ')
    query = "
      UPDATE #{@_table} SET #{joined_values}
      WHERE #{@_pkey} = #{@_pkey_id}
    "

    Taupe::Database.exec query
  end

  Taupe::Cache.delete @_cache_key unless @_cache_key.nil?
end