Class: SimpleMaster::Master

Inherits:
Object
  • Object
show all
Extended by:
Dsl, Filterable, Queryable, Storable
Includes:
Validatable
Defined in:
lib/simple_master/master.rb,
lib/simple_master/master/dsl.rb,
lib/simple_master/master/column.rb,
lib/simple_master/master/editable.rb,
lib/simple_master/master/storable.rb,
lib/simple_master/master/queryable.rb,
lib/simple_master/master/filterable.rb,
lib/simple_master/master/association.rb,
lib/simple_master/master/validatable.rb,
lib/simple_master/master/column/id_column.rb,
lib/simple_master/master/column/enum_column.rb,
lib/simple_master/master/column/json_column.rb,
lib/simple_master/master/column/time_column.rb,
lib/simple_master/master/column/float_column.rb,
lib/simple_master/master/column/string_column.rb,
lib/simple_master/master/column/symbol_column.rb,
lib/simple_master/master/column/bitmask_column.rb,
lib/simple_master/master/column/boolean_column.rb,
lib/simple_master/master/column/integer_column.rb,
lib/simple_master/master/column/sti_type_column.rb,
lib/simple_master/master/column/polymorphic_type_column.rb,
lib/simple_master/master/association/has_one_association.rb,
lib/simple_master/master/association/has_many_association.rb,
lib/simple_master/master/association/belongs_to_association.rb,
lib/simple_master/master/association/has_many_through_association.rb,
lib/simple_master/master/association/belongs_to_polymorphic_association.rb

Defined Under Namespace

Modules: Dsl, Editable, Filterable, Queryable, Storable, SubClassStorable, Validatable Classes: Association, Column, Errors, UniquenessValidator

Constant Summary

Constants included from Dsl

Dsl::TYPES_BY_OPTIONS

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Dsl

belongs_to, bitmask, cache_attribute, cache_class_method, cache_method, def_column, enum, globalize, group_key, has_many, has_one, tap_instance_method

Methods included from Filterable

all_by, all_by!, all_in, exists?, find, find_by, find_by_id, find_by_ids, find_by_ids!

Methods included from Storable

master_storage

Methods included from Queryable

connection, delete_all_query, insert_queries, query_delete_all, query_select_all, query_upsert_records, sqlite_insert_query, table_available?

Methods included from Validatable

#_run_validate_callbacks, #errors, #read_attribute_for_validation, #run_proc_or_call, #valid?, #validate

Constructor Details

#initialize(attributes = nil) {|_self| ... } ⇒ Master

Returns a new instance of Master.

Yields:

  • (_self)

Yield Parameters:



406
407
408
409
410
411
# File 'lib/simple_master/master.rb', line 406

def initialize(attributes = nil)
  attributes&.each do |key, value|
    send :"#{key}=", value
  end
  yield self if block_given?
end

Class Attribute Details

.abstract_classObject

Returns the value of attribute abstract_class.



21
22
23
# File 'lib/simple_master/master.rb', line 21

def abstract_class
  @abstract_class
end

.class_method_cache_infoObject (readonly)

: Array[[Symbol, Proc]]



257
258
259
# File 'lib/simple_master/master.rb', line 257

def class_method_cache_info
  @class_method_cache_info
end

.default_objectObject (readonly)

: self



259
260
261
# File 'lib/simple_master/master.rb', line 259

def default_object
  @default_object
end

.instance_methods_need_tapObject (readonly)

: Array



258
259
260
# File 'lib/simple_master/master.rb', line 258

def instance_methods_need_tap
  @instance_methods_need_tap
end

.object_cacheObject (readonly)

: Hash[Symbol, untyped]



260
261
262
# File 'lib/simple_master/master.rb', line 260

def object_cache
  @object_cache
end

Class Method Details

._build_associations(is_database_available, for_test) ⇒ Object

: () -> void



238
239
240
241
242
243
244
245
246
# File 'lib/simple_master/master.rb', line 238

def _build_associations(is_database_available, for_test)
  associations = has_one_associations + has_many_associations + belongs_to_associations

  associations.each do |association|
    next if !is_database_available && association.is_active_record?
    association.init(self)
    association.init_for_test(self) if for_test
  end
end

._build_columns(for_test) ⇒ Object

: () -> void



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/simple_master/master.rb', line 188

def _build_columns(for_test)
  columns.each do |column|
    column.init(self, for_test)
  end

  @group_keys = group_keys

  simple_master_module.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def attributes
      {
        #{
          all_columns.map { |column| "#{column.name}: #{column.name}" }.join(",\n")
        }
      }
    end

    def db_attributes
      {
        #{
          all_columns.map { |column| "#{column.db_column_name}: #{column.name}_value_for_csv" }.join(",\n")
        }
      }
    end

    def globalized_db_attributes
      {
        #{
          all_columns.map { |column| "#{column.db_column_name}: #{column.name}_value_for_csv" }.join(",\n")
        },
        #{
          all_columns.select { |column| column.options[:globalize] }.map { |column|
            "_globalized_#{column.name}: _globalized_#{column.name}"
          }.join(",\n")
        }
      }
    end

    def create_copy
      r = self.class.default_object.dup
      #{
        all_columns.map { |column| "r.#{column.name} = #{column.name}" }.join("\n")
      }
      r
    end
  RUBY

  build_default_object
end

._build_dslObject

: () -> void



183
184
185
# File 'lib/simple_master/master.rb', line 183

def _build_dsl
  dsl_initializers.each(&:call)
end

._build_sti_methodsObject



248
249
250
# File 'lib/simple_master/master.rb', line 248

def _build_sti_methods
  extend SubClassStorable if sti_sub_class?
end

.abstract_class?Boolean

: () -> bool



24
25
26
# File 'lib/simple_master/master.rb', line 24

def abstract_class?
  !!abstract_class
end

.all_belongs_to_associationsObject



115
116
117
118
119
120
121
# File 'lib/simple_master/master.rb', line 115

def all_belongs_to_associations
  if superclass < SimpleMaster::Master
    superclass.all_belongs_to_associations + belongs_to_associations
  else
    belongs_to_associations
  end
end

.all_class_method_cache_infoObject



263
264
265
266
267
268
269
# File 'lib/simple_master/master.rb', line 263

def all_class_method_cache_info
  if superclass < SimpleMaster::Master
    superclass.all_class_method_cache_info + (class_method_cache_info || EMPTY_ARRAY)
  else
    class_method_cache_info || EMPTY_ARRAY
  end
end

.all_columnsObject

: () -> Array



53
54
55
56
57
58
59
# File 'lib/simple_master/master.rb', line 53

def all_columns
  if superclass < SimpleMaster::Master
    (superclass.all_columns + columns).reverse.uniq(&:name).reverse
  else
    columns
  end
end

.all_has_many_associationsObject



103
104
105
106
107
108
109
# File 'lib/simple_master/master.rb', line 103

def all_has_many_associations
  if superclass < SimpleMaster::Master
    superclass.all_has_many_associations + has_many_associations
  else
    has_many_associations
  end
end

.all_has_one_associationsObject



91
92
93
94
95
96
97
# File 'lib/simple_master/master.rb', line 91

def all_has_one_associations
  if superclass < SimpleMaster::Master
    superclass.all_has_one_associations + has_one_associations
  else
    has_one_associations
  end
end

.base_classObject



286
287
288
# File 'lib/simple_master/master.rb', line 286

def base_class
  sti_base_class || self
end

.base_class?Boolean



290
291
292
# File 'lib/simple_master/master.rb', line 290

def base_class?
  !sti_base_class || sti_base_class?
end

.belongs_to_associationsObject



111
112
113
# File 'lib/simple_master/master.rb', line 111

def belongs_to_associations
  @belongs_to_associations ||= []
end

.build_default_objectObject

: () -> void



304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/simple_master/master.rb', line 304

def build_default_object
  default_object = allocate

  all_columns.each do |column|
    # Assign nil even when undefined to keep this fast
    default_object.send :"#{column.name}=", column.options[:default].freeze
    default_object.send :"_globalized_#{column.name}=", nil if column.options[:globalize]
  end
  default_object.type = name if sti_class?

  @default_object = default_object
end

.column_namesObject

: () -> Array



77
78
79
# File 'lib/simple_master/master.rb', line 77

def column_names
  all_columns.map(&:name)
end

.columnsObject

: () -> Array



48
49
50
# File 'lib/simple_master/master.rb', line 48

def columns
  @columns ||= []
end

.columns_hashObject

Unlike ActiveRecord, we ensure column existence can be checked. : () -> Hash[String, SimpleMaster::Master::Column]



83
84
85
# File 'lib/simple_master/master.rb', line 83

def columns_hash
  all_columns.index_by(&:name).with_indifferent_access
end

.composite_primary_key?Boolean



149
150
151
# File 'lib/simple_master/master.rb', line 149

def composite_primary_key?
  false
end

.current_scopeObject



157
158
159
160
161
162
# File 'lib/simple_master/master.rb', line 157

def current_scope
  fail
  # pp caller
  # raise
  # @current_scope ||= Scope.new
end

.dsl_initializersObject

: () -> void



178
179
180
# File 'lib/simple_master/master.rb', line 178

def dsl_initializers
  @dsl_initializers ||= []
end

.globalized?Boolean



294
295
296
# File 'lib/simple_master/master.rb', line 294

def globalized?
  all_columns.any? { |column| column.options[:globalize] }
end

.group_keysObject



123
124
125
# File 'lib/simple_master/master.rb', line 123

def group_keys
  @group_keys || all_columns.select(&:group_key).map(&:name)
end

.has_many_associationsObject



99
100
101
# File 'lib/simple_master/master.rb', line 99

def has_many_associations
  @has_many_associations ||= []
end

.has_one_associationsObject



87
88
89
# File 'lib/simple_master/master.rb', line 87

def has_one_associations
  @has_one_associations ||= []
end

.has_query_constraints?Boolean



145
146
147
# File 'lib/simple_master/master.rb', line 145

def has_query_constraints?
  false
end

.idsObject

: () -> Array



43
44
45
# File 'lib/simple_master/master.rb', line 43

def ids
  id_hash.keys
end

.inherited(subclass) ⇒ Object



252
253
254
255
# File 'lib/simple_master/master.rb', line 252

def inherited(subclass)
  super
  subclass.include(subclass.simple_master_module)
end

.init(database_available = true, for_test: false) ⇒ Object

: () -> void



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/simple_master/master.rb', line 165

def init(database_available = true, for_test: false)
  @object_cache = Hash.new { |k, v| k[v] = {} }

  _build_dsl
  _build_columns(for_test)
  _build_associations(database_available, for_test)
  _build_sti_methods

  # Override on test env.
  define_method(:cache_object) { |_column, input, &block| block.call(input) } if for_test
end

.new(attributes = nil) ⇒ Object



413
414
415
# File 'lib/simple_master/master.rb', line 413

def self.new(attributes = nil, &)
  default_object.dup.tap { _1.send(:initialize, attributes, &) }
end

.primary_keyObject



138
139
140
# File 'lib/simple_master/master.rb', line 138

def primary_key
  :id
end

.reset_object_cacheObject

: () -> void



299
300
301
# File 'lib/simple_master/master.rb', line 299

def reset_object_cache
  @object_cache.clear
end

.scope(*_option) ⇒ Object



271
272
# File 'lib/simple_master/master.rb', line 271

def scope(*_option)
end

.simple_master_moduleObject

Auto-generated methods live in a module so they can be overridden.



34
35
36
# File 'lib/simple_master/master.rb', line 34

def simple_master_module
  @simple_master_module ||= Module.new
end

.sti_base_classObject



127
128
129
# File 'lib/simple_master/master.rb', line 127

def sti_base_class
  nil
end

.sti_base_class?Boolean



278
279
280
# File 'lib/simple_master/master.rb', line 278

def sti_base_class?
  sti_base_class == self
end

.sti_class?Boolean



274
275
276
# File 'lib/simple_master/master.rb', line 274

def sti_class?
  !!sti_base_class
end

.sti_columnObject Also known as: inheritance_column



131
132
133
# File 'lib/simple_master/master.rb', line 131

def sti_column
  nil
end

.sti_sub_class?Boolean



282
283
284
# File 'lib/simple_master/master.rb', line 282

def sti_sub_class?
  !!sti_base_class && sti_base_class != self
end

.table_exists?Boolean

: () -> bool



29
30
31
# File 'lib/simple_master/master.rb', line 29

def table_exists?
  table_available?
end

.table_nameObject



153
154
155
# File 'lib/simple_master/master.rb', line 153

def table_name
  ActiveSupport::Inflector.tableize(base_class.to_s).tr("/", "_")
end

.update_column_info(name) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/simple_master/master.rb', line 61

def update_column_info(name)
  if (column_index = columns.find_index { _1.name == name })
    columns[column_index] = yield(columns[column_index])
    return
  end

  if (column_from_parent = superclass.all_columns.find { _1.name == name })
    new_column = yield(column_from_parent)
    columns << new_column
    return
  end

  fail "Column #{name} not found on #{self}!"
end

Instance Method Details

#_read_attribute(key) ⇒ Object Also known as: read_attribute



345
346
347
# File 'lib/simple_master/master.rb', line 345

def _read_attribute(key)
  instance_variable_get("@#{key}")
end

#as_json(_option = nil) ⇒ Object



355
356
357
# File 'lib/simple_master/master.rb', line 355

def as_json(_option = nil)
  attributes
end

#belongs_to_storeObject



335
336
337
338
# File 'lib/simple_master/master.rb', line 335

def belongs_to_store
  RequestStore.store[:belongs_to_store] ||= {}.compare_by_identity
  RequestStore.store[:belongs_to_store][self] ||= {}
end

#cache_object(column, input) ⇒ Object

: (Symbol, untyped) { (untyped) -> untyped } -> untyped



319
320
321
322
# File 'lib/simple_master/master.rb', line 319

def cache_object(column, input)
  cache = self.class.base_class.object_cache[column]
  cache.fetch(input) { cache[input] = yield(input) }
end

#destroyObject



396
397
# File 'lib/simple_master/master.rb', line 396

def destroy
end

#destroy!Object



399
400
# File 'lib/simple_master/master.rb', line 399

def destroy!
end

#destroyed?Boolean

: () -> bool



365
366
367
# File 'lib/simple_master/master.rb', line 365

def destroyed?
  false
end

#dirty!Object



340
341
# File 'lib/simple_master/master.rb', line 340

def dirty!
end

#has_changes_to_save?Boolean

: () -> bool



375
376
377
# File 'lib/simple_master/master.rb', line 375

def has_changes_to_save?
  false
end

#has_many_storeObject



330
331
332
333
# File 'lib/simple_master/master.rb', line 330

def has_many_store
  RequestStore.store[:has_many_store] ||= {}.compare_by_identity
  RequestStore.store[:has_many_store][self] ||= {}
end

#inspectObject



402
403
404
# File 'lib/simple_master/master.rb', line 402

def inspect
  "#<#{self.class.name}:#{'%#016x' % (object_id << 1)} #{attributes.inspect}>"
end

#instance_storeObject



324
325
326
327
328
# File 'lib/simple_master/master.rb', line 324

def instance_store
  store = RequestStore.store
  instance_store = store.fetch(:instance_store) { store[:instance_store] = Hash.new { |hash, key| hash[key] = {} }.compare_by_identity }
  instance_store[self]
end

#json_slice(*attrs) ⇒ Object

for comparing in test.



360
361
362
# File 'lib/simple_master/master.rb', line 360

def json_slice(*attrs)
  JSON.parse(slice(*attrs).to_json)
end

#marked_for_destruction?Boolean

: () -> bool



380
381
382
# File 'lib/simple_master/master.rb', line 380

def marked_for_destruction?
  false
end

#new_record?Boolean

: () -> bool



370
371
372
# File 'lib/simple_master/master.rb', line 370

def new_record?
  false
end

#save(*_) ⇒ Object



384
385
# File 'lib/simple_master/master.rb', line 384

def save(*_)
end

#save!(*_) ⇒ Object



387
388
# File 'lib/simple_master/master.rb', line 387

def save!(*_)
end

#slice(*attrs) ⇒ Object



351
352
353
# File 'lib/simple_master/master.rb', line 351

def slice(*attrs)
  attrs.index_with { send(_1) }
end

#update(*_) ⇒ Object



390
391
# File 'lib/simple_master/master.rb', line 390

def update(*_)
end

#update!(*_) ⇒ Object



393
394
# File 'lib/simple_master/master.rb', line 393

def update!(*_)
end