superstore 1.2.0 → 2.0.0

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -13
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile +0 -5
  5. data/README.md +15 -33
  6. data/lib/superstore/adapters/jsonb_adapter.rb +245 -0
  7. data/lib/superstore/associations/association.rb +38 -0
  8. data/lib/superstore/associations/belongs_to.rb +35 -0
  9. data/lib/superstore/associations/builder/association.rb +38 -0
  10. data/lib/superstore/associations/builder/belongs_to.rb +7 -0
  11. data/lib/superstore/associations/builder/has_many.rb +7 -0
  12. data/lib/superstore/associations/builder/has_one.rb +7 -0
  13. data/lib/superstore/associations/has_many.rb +26 -0
  14. data/lib/superstore/associations/has_one.rb +24 -0
  15. data/lib/superstore/associations/reflection.rb +65 -0
  16. data/lib/superstore/associations.rb +72 -0
  17. data/lib/superstore/attribute_methods/definition.rb +5 -10
  18. data/lib/superstore/attribute_methods/dirty.rb +12 -2
  19. data/lib/superstore/attribute_methods/typecasting.rb +6 -12
  20. data/lib/superstore/base.rb +3 -4
  21. data/lib/superstore/connection.rb +3 -5
  22. data/lib/superstore/core.rb +0 -5
  23. data/lib/superstore/model.rb +32 -33
  24. data/lib/superstore/persistence.rb +4 -10
  25. data/lib/superstore/railtie.rb +2 -20
  26. data/lib/superstore/scope/batches.rb +17 -22
  27. data/lib/superstore/scope/finder_methods.rb +33 -35
  28. data/lib/superstore/scope/query_methods.rb +38 -44
  29. data/lib/superstore/scope.rb +24 -0
  30. data/lib/superstore/type.rb +3 -3
  31. data/lib/superstore/types/array_type.rb +2 -9
  32. data/lib/superstore/types/base_type.rb +4 -7
  33. data/lib/superstore/types/boolean_type.rb +2 -1
  34. data/lib/superstore/types/float_type.rb +6 -5
  35. data/lib/superstore/types/integer_type.rb +3 -3
  36. data/lib/superstore/types/json_type.rb +0 -21
  37. data/lib/superstore.rb +16 -5
  38. data/superstore.gemspec +2 -1
  39. data/test/support/jsonb.rb +8 -0
  40. data/test/support/{issue.rb → models.rb} +9 -0
  41. data/test/support/pg.rb +11 -15
  42. data/test/test_helper.rb +7 -6
  43. data/test/unit/{belongs_to_test.rb → associations/belongs_to_test.rb} +1 -10
  44. data/test/unit/associations/has_many_test.rb +13 -0
  45. data/test/unit/associations/has_one_test.rb +14 -0
  46. data/test/unit/{belongs_to → associations}/reflection_test.rb +2 -2
  47. data/test/unit/attribute_methods/definition_test.rb +6 -3
  48. data/test/unit/attribute_methods/dirty_test.rb +17 -14
  49. data/test/unit/attribute_methods/typecasting_test.rb +0 -14
  50. data/test/unit/base_test.rb +3 -3
  51. data/test/unit/connection_test.rb +0 -4
  52. data/test/unit/persistence_test.rb +4 -4
  53. data/test/unit/schema_test.rb +9 -17
  54. data/test/unit/scope/query_methods_test.rb +10 -1
  55. data/test/unit/types/array_type_test.rb +12 -10
  56. data/test/unit/types/base_type_test.rb +2 -10
  57. data/test/unit/types/boolean_type_test.rb +15 -13
  58. data/test/unit/types/date_type_test.rb +3 -3
  59. data/test/unit/types/float_type_test.rb +14 -7
  60. data/test/unit/types/integer_type_test.rb +11 -9
  61. data/test/unit/types/json_type_test.rb +0 -23
  62. data/test/unit/types/string_type_test.rb +6 -6
  63. data/test/unit/types/time_type_test.rb +7 -7
  64. metadata +35 -26
  65. data/CHANGELOG +0 -0
  66. data/lib/superstore/adapters/cassandra_adapter.rb +0 -203
  67. data/lib/superstore/adapters/hstore_adapter.rb +0 -170
  68. data/lib/superstore/belongs_to/association.rb +0 -65
  69. data/lib/superstore/belongs_to/builder.rb +0 -40
  70. data/lib/superstore/belongs_to/reflection.rb +0 -38
  71. data/lib/superstore/belongs_to.rb +0 -63
  72. data/lib/superstore/cassandra_schema/statements.rb +0 -52
  73. data/lib/superstore/cassandra_schema/tasks.rb +0 -47
  74. data/lib/superstore/cassandra_schema.rb +0 -9
  75. data/lib/superstore/log_subscriber.rb +0 -44
  76. data/lib/superstore/railties/controller_runtime.rb +0 -45
  77. data/lib/superstore/tasks/ks.rake +0 -59
  78. data/test/support/cassandra.rb +0 -46
  79. data/test/support/hstore.rb +0 -24
  80. data/test/support/user.rb +0 -2
  81. data/test/unit/cassandra_schema/statements_test.rb +0 -47
  82. data/test/unit/cassandra_schema/tasks_test.rb +0 -31
  83. data/test/unit/log_subscriber_test.rb +0 -26
  84. data/test/unit/railties/controller_runtime_test.rb +0 -48
@@ -0,0 +1,72 @@
1
+ module Superstore
2
+ module Associations
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :association_reflections
7
+ self.association_reflections = {}
8
+ end
9
+
10
+ module ClassMethods
11
+ # === Options
12
+ # [:class_name]
13
+ # Use if the class cannot be inferred from the association
14
+ # [:polymorphic]
15
+ # Specify if the association is polymorphic
16
+ # Example:
17
+ # class Driver < Superstore::Base
18
+ # end
19
+ # class Truck < Superstore::Base
20
+ # end
21
+ def belongs_to(name, options = {})
22
+ Superstore::Associations::Builder::BelongsTo.build(self, name, options)
23
+ end
24
+
25
+ def has_many(name, options = {})
26
+ Superstore::Associations::Builder::HasMany.build(self, name, options)
27
+ end
28
+
29
+ def has_one(name, options = {})
30
+ Superstore::Associations::Builder::HasOne.build(self, name, options)
31
+ end
32
+
33
+ def generated_association_methods
34
+ @generated_association_methods ||= begin
35
+ mod = const_set(:GeneratedAssociationMethods, Module.new)
36
+ include mod
37
+ mod
38
+ end
39
+ end
40
+ end
41
+
42
+ # Returns the belongs_to instance for the given name, instantiating it if it doesn't already exist
43
+ def association(name)
44
+ instance = association_instance_get(name)
45
+
46
+ if instance.nil?
47
+ reflection = association_reflections[name]
48
+ instance = reflection.association_class.new(self, reflection)
49
+ association_instance_set(name, instance)
50
+ end
51
+
52
+ instance
53
+ end
54
+
55
+ private
56
+ def clear_associations_cache
57
+ associations_cache.clear if persisted?
58
+ end
59
+
60
+ def associations_cache
61
+ @associations_cache ||= {}
62
+ end
63
+
64
+ def association_instance_get(name)
65
+ associations_cache[name.to_sym]
66
+ end
67
+
68
+ def association_instance_set(name, association)
69
+ associations_cache[name.to_sym] = association
70
+ end
71
+ end
72
+ end
@@ -1,21 +1,16 @@
1
1
  module Superstore
2
2
  module AttributeMethods
3
3
  class Definition
4
- attr_reader :name, :coder
5
- def initialize(name, coder, options)
6
- @name = name.to_s
7
- @coder = coder.new(options)
8
- end
9
-
10
- def default
11
- coder.default
4
+ attr_reader :name, :type
5
+ def initialize(model, name, type_class, options)
6
+ @name = name.to_s
7
+ @type = type_class.new(model, options)
12
8
  end
13
9
 
14
10
  def instantiate(value)
15
- value = value.nil? ? coder.default : value
16
11
  return if value.nil?
17
12
 
18
- value.kind_of?(String) ? coder.decode(value) : coder.typecast(value)
13
+ value.kind_of?(String) ? type.decode(value) : type.typecast(value)
19
14
  end
20
15
  end
21
16
  end
@@ -27,13 +27,23 @@ module Superstore
27
27
  result
28
28
  end
29
29
 
30
+ def old_attribute_value(attr)
31
+ if attribute_changed?(attr)
32
+ changed_attributes[attr]
33
+ else
34
+ read_attribute attr
35
+ end
36
+ end
37
+
30
38
  def write_attribute(name, value)
31
39
  name = name.to_s
32
- old = read_attribute(name)
40
+ old = old_attribute_value(name)
33
41
 
34
42
  super
35
43
 
36
- unless attribute_changed?(name) || old == read_attribute(name)
44
+ if old == read_attribute(name)
45
+ changed_attributes.delete(name)
46
+ else
37
47
  changed_attributes[name] = old
38
48
  end
39
49
  end
@@ -27,19 +27,13 @@ module Superstore
27
27
 
28
28
  #
29
29
  # attribute :name, type: :string
30
- # attribute :ammo, type: Ammo, coder: AmmoCodec
30
+ # attribute :ammo, type: :integer
31
31
  #
32
32
  def attribute(name, options)
33
- type = options[:type]
34
- coder = options[:coder]
33
+ type_name = options[:type]
34
+ type_class = Superstore::Type.get_type_class(type_name) || (raise "Unknown type #{type_name}")
35
35
 
36
- if type.is_a?(Symbol)
37
- coder = Superstore::Type.get_coder(type) || (raise "Unknown type #{type}")
38
- elsif coder.nil?
39
- raise "Must supply a :coder for #{name}"
40
- end
41
-
42
- attribute_definitions[name.to_s] = AttributeMethods::Definition.new(name, coder, options)
36
+ attribute_definitions[name.to_s] = AttributeMethods::Definition.new(self, name, type_class, options)
43
37
  end
44
38
 
45
39
  def typecast_attribute(name, value)
@@ -50,8 +44,8 @@ module Superstore
50
44
  end
51
45
  end
52
46
 
53
- def coder_for(attribute)
54
- attribute_definitions[attribute.to_s].coder
47
+ def type_for(attribute)
48
+ attribute_definitions[attribute.to_s].type
55
49
  end
56
50
  end
57
51
  end
@@ -1,6 +1,5 @@
1
1
  require 'set'
2
2
 
3
- require 'superstore/log_subscriber'
4
3
  require 'superstore/types'
5
4
 
6
5
  module Superstore
@@ -12,6 +11,8 @@ module Superstore
12
11
  include ActiveModel::Serializers::JSON
13
12
  include GlobalID::Identification
14
13
 
14
+ include Model
15
+ include Core
15
16
  include Connection
16
17
  include Identity
17
18
  include Inspect
@@ -21,13 +22,11 @@ module Superstore
21
22
  include AttributeMethods::Dirty
22
23
  include AttributeMethods::PrimaryKey
23
24
  include AttributeMethods::Typecasting
24
- include BelongsTo
25
+ include Associations
25
26
  include Callbacks
26
27
  include Timestamps
27
28
  include Scoping
28
- include Core
29
29
  include Caching
30
- extend Model
31
30
 
32
31
  end
33
32
  end
@@ -4,15 +4,13 @@ module Superstore
4
4
 
5
5
  module ClassMethods
6
6
  def adapter
7
- @@adapter ||= adapter_class.new(config)
7
+ @adapter ||= adapter_class.new(config)
8
8
  end
9
9
 
10
10
  def adapter_class
11
11
  case config[:adapter]
12
- when 'hstore'
13
- Superstore::Adapters::HstoreAdapter
14
- when nil, 'cassandra'
15
- Superstore::Adapters::CassandraAdapter
12
+ when nil, 'jsonb'
13
+ Superstore::Adapters::JsonbAdapter
16
14
  else
17
15
  raise "Unknown adapter #{config[:adapter]}"
18
16
  end
@@ -7,11 +7,6 @@ module Superstore
7
7
  @destroyed = false
8
8
  @attributes = {}
9
9
  self.attributes = attributes || {}
10
- attribute_definitions.each_value do |definition|
11
- unless definition.default.nil? || attribute_exists?(definition.name)
12
- @attributes[definition.name] = definition.default
13
- end
14
- end
15
10
 
16
11
  yield self if block_given?
17
12
  end
@@ -1,46 +1,45 @@
1
1
  module Superstore
2
2
  module Model
3
- def table_name=(table_name)
4
- @table_name = table_name
5
- end
3
+ extend ActiveSupport::Concern
6
4
 
7
- def table_name
8
- @table_name ||= base_class.name.pluralize
5
+ included do
6
+ class_attribute :symbolized_config
7
+ self.symbolized_config = {}
9
8
  end
10
9
 
11
- def column_family
12
- ActiveSupport::Deprecation.warn '`column_family` is deprecated & will be removed in superstore 2.0. Use `table_name` instead.'
13
- table_name
14
- end
10
+ module ClassMethods
11
+ def table_name=(table_name)
12
+ @table_name = table_name
13
+ end
15
14
 
16
- def column_family=(table_name)
17
- ActiveSupport::Deprecation.warn '`column_family=` is deprecated & will be removed in superstore 2.0. Use `table_name=` instead.'
18
- self.table_name = table_name
19
- end
15
+ def table_name
16
+ @table_name ||= base_class.model_name.plural
17
+ end
20
18
 
21
- def base_class
22
- class_of_active_record_descendant(self)
23
- end
19
+ def base_class
20
+ class_of_active_record_descendant(self)
21
+ end
24
22
 
25
- def config=(config)
26
- @@config = config.deep_symbolize_keys
27
- end
23
+ def config=(config)
24
+ self.symbolized_config = config.deep_symbolize_keys
25
+ end
28
26
 
29
- def config
30
- @@config
31
- end
27
+ def config
28
+ symbolized_config
29
+ end
32
30
 
33
- private
34
-
35
- # Returns the class descending directly from ActiveRecord::Base or an
36
- # abstract class, if any, in the inheritance hierarchy.
37
- def class_of_active_record_descendant(klass)
38
- if klass == Base || klass.superclass == Base
39
- klass
40
- elsif klass.superclass.nil?
41
- raise "#{name} doesn't belong in a hierarchy descending from Superstore"
42
- else
43
- class_of_active_record_descendant(klass.superclass)
31
+ private
32
+
33
+ # Returns the class descending directly from ActiveRecord::Base or an
34
+ # abstract class, if any, in the inheritance hierarchy.
35
+ def class_of_active_record_descendant(klass)
36
+ if klass == Base || klass.superclass == Base
37
+ klass
38
+ elsif klass.superclass.nil?
39
+ raise "#{name} doesn't belong in a hierarchy descending from Superstore"
40
+ else
41
+ class_of_active_record_descendant(klass.superclass)
42
+ end
44
43
  end
45
44
  end
46
45
  end
@@ -7,7 +7,7 @@ module Superstore
7
7
  end
8
8
 
9
9
  module ClassMethods
10
- def remove(ids)
10
+ def delete(ids)
11
11
  adapter.delete table_name, ids
12
12
  end
13
13
 
@@ -52,7 +52,7 @@ module Superstore
52
52
  if value.nil?
53
53
  encoded[column_name] = nil
54
54
  else
55
- encoded[column_name] = attribute_definitions[column_name].coder.encode(value)
55
+ encoded[column_name] = attribute_definitions[column_name].type.encode(value)
56
56
  end
57
57
  end
58
58
  encoded
@@ -73,12 +73,6 @@ module Superstore
73
73
  end
74
74
  end
75
75
 
76
- attribute_definitions.each_value do |definition|
77
- unless definition.default.nil? || result.has_key?(definition.name)
78
- result[definition.name] = definition.default
79
- end
80
- end
81
-
82
76
  result
83
77
  end
84
78
  end
@@ -100,7 +94,7 @@ module Superstore
100
94
  end
101
95
 
102
96
  def destroy
103
- self.class.remove(id)
97
+ self.class.delete(id)
104
98
  @destroyed = true
105
99
  end
106
100
 
@@ -133,7 +127,7 @@ module Superstore
133
127
  end
134
128
 
135
129
  def reload
136
- clear_belongs_to_cache
130
+ clear_associations_cache
137
131
  @attributes = self.class.find(id).instance_variable_get('@attributes')
138
132
  self
139
133
  end
@@ -1,19 +1,9 @@
1
1
  module Superstore
2
2
  class Railtie < Rails::Railtie
3
- rake_tasks do
4
- load 'superstore/tasks/ks.rake'
5
- end
6
-
7
3
  initializer "superstore.config" do |app|
8
4
  ActiveSupport.on_load :superstore do
9
- pathnames = [Rails.root.join('config', 'cassandra.yml'), Rails.root.join('config', 'superstore.yml')]
10
- if pathname = pathnames.detect(&:exist?)
11
- if pathname.basename.to_s == 'cassandra.yml'
12
- warn "***********************"
13
- warn "config/cassandra.yml is deprecated. Use config/superstore.yml"
14
- warn "***********************"
15
- end
16
-
5
+ pathname = Rails.root.join('config', 'superstore.yml')
6
+ if pathname.exist?
17
7
  config = ERB.new(pathname.read).result
18
8
  config = YAML.load(config)
19
9
 
@@ -25,13 +15,5 @@ module Superstore
25
15
  end
26
16
  end
27
17
  end
28
-
29
- # Expose database runtime to controller for logging.
30
- initializer "superstore.log_runtime" do |app|
31
- require "superstore/railties/controller_runtime"
32
- ActiveSupport.on_load(:action_controller) do
33
- include Superstore::Railties::ControllerRuntime
34
- end
35
- end
36
18
  end
37
19
  end
@@ -1,32 +1,27 @@
1
1
  module Superstore
2
- class Scope
3
- module Batches
4
- def find_each(options = {})
5
- find_in_batches(options) do |records|
6
- records.each { |record| yield record }
7
- end
8
- end
9
-
10
- def find_in_batches(options = {})
11
- batch_size = options.delete(:batch_size) || 1000
12
- start_key = nil
2
+ module Batches
3
+ def find_each(options = {})
4
+ batch_size = options[:batch_size] || 1000
13
5
 
14
- scope = limit(batch_size + 1).order(:id)
15
- records = scope.to_a
6
+ klass.adapter.scroll(self, batch_size) do |key, attributes|
7
+ yield klass.instantiate(key, attributes)
8
+ end
9
+ end
16
10
 
17
- while records.any?
18
- if records.size > batch_size
19
- next_record = records.pop
20
- else
21
- next_record = nil
22
- end
11
+ def find_in_batches(options = {})
12
+ batch_size = options[:batch_size] || 1000
13
+ batch = []
23
14
 
24
- yield records
25
- break if next_record.nil?
15
+ find_each(options) do |record|
16
+ batch << record
26
17
 
27
- records = scope.where("#{adapter.primary_key_column} >= '#{next_record.id}'").to_a
18
+ if batch.size == batch_size
19
+ yield batch
20
+ batch = []
28
21
  end
29
22
  end
23
+
24
+ yield(batch) if batch.any?
30
25
  end
31
26
  end
32
27
  end
@@ -1,48 +1,46 @@
1
1
  module Superstore
2
- class Scope
3
- module FinderMethods
4
- def find(ids)
5
- if ids.is_a?(Array)
6
- find_some(ids)
7
- else
8
- find_one(ids)
9
- end
2
+ module FinderMethods
3
+ def find(ids)
4
+ if ids.is_a?(Array)
5
+ find_some(ids)
6
+ else
7
+ find_one(ids)
10
8
  end
9
+ end
11
10
 
12
- def find_by_id(ids)
13
- find(ids)
14
- rescue Superstore::RecordNotFound
15
- nil
16
- end
11
+ def find_by_id(ids)
12
+ find(ids)
13
+ rescue Superstore::RecordNotFound
14
+ nil
15
+ end
17
16
 
18
- def all
19
- to_a
20
- end
17
+ def all
18
+ clone
19
+ end
21
20
 
22
- def first
23
- limit(1).to_a.first
24
- end
21
+ def first
22
+ limit(1).to_a.first
23
+ end
25
24
 
26
- private
25
+ private
27
26
 
28
- def find_one(id)
29
- if id.blank?
30
- raise Superstore::RecordNotFound, "Couldn't find #{self.name} with key #{id.inspect}"
31
- elsif record = where_ids(id).first
32
- record
33
- else
34
- raise Superstore::RecordNotFound
35
- end
27
+ def find_one(id)
28
+ if id.blank?
29
+ raise Superstore::RecordNotFound, "Couldn't find #{self.name} with key #{id.inspect}"
30
+ elsif record = where_ids(id).first
31
+ record
32
+ else
33
+ raise Superstore::RecordNotFound
36
34
  end
35
+ end
37
36
 
38
- def find_some(ids)
39
- ids = ids.flatten
40
- return [] if ids.empty?
37
+ def find_some(ids)
38
+ ids = ids.flatten
39
+ return [] if ids.empty?
41
40
 
42
- ids = ids.compact.map(&:to_s).uniq
41
+ ids = ids.compact.map(&:to_s).uniq
43
42
 
44
- where_ids(ids).to_a
45
- end
46
- end
43
+ where_ids(ids).to_a
44
+ end
47
45
  end
48
46
  end
@@ -1,58 +1,52 @@
1
1
  module Superstore
2
- class Scope
3
- module QueryMethods
4
- def select!(*values)
5
- self.select_values += values.flatten
6
- self
7
- end
8
-
9
- def select(*values, &block)
10
- if block_given?
11
- to_a.select(&block)
12
- else
13
- clone.select! *values
14
- end
15
- end
2
+ module QueryMethods
3
+ def select!(*values)
4
+ self.select_values += values.flatten
5
+ self
6
+ end
16
7
 
17
- def where!(*values)
18
- self.where_values += values.flatten
19
- self
8
+ def select(*values, &block)
9
+ if block_given?
10
+ to_a.select(&block)
11
+ else
12
+ clone.select! *values
20
13
  end
14
+ end
21
15
 
22
- def where(*values)
23
- clone.where! values
24
- end
16
+ def where!(*values)
17
+ self.where_values += values.flatten
18
+ self
19
+ end
25
20
 
26
- def where_ids!(*ids)
27
- self.id_values += ids.flatten
28
- self
29
- end
21
+ def where(*values)
22
+ clone.where! values
23
+ end
30
24
 
31
- def where_ids(*ids)
32
- clone.where_ids! ids
33
- end
25
+ def where_ids!(*ids)
26
+ self.id_values += ids.flatten
27
+ self
28
+ end
34
29
 
35
- def limit!(value)
36
- self.limit_value = value
37
- self
38
- end
30
+ def where_ids(*ids)
31
+ clone.where_ids! ids
32
+ end
39
33
 
40
- def limit(value)
41
- clone.limit! value
42
- end
34
+ def limit!(value)
35
+ self.limit_value = value
36
+ self
37
+ end
43
38
 
44
- def order!(*values)
45
- self.order_values = values.flatten
46
- self
47
- end
39
+ def limit(value)
40
+ clone.limit! value
41
+ end
48
42
 
49
- def order(*values)
50
- clone.order! values
51
- end
43
+ def order!(*values)
44
+ self.order_values = values.flatten
45
+ self
46
+ end
52
47
 
53
- def to_a
54
- select_records
55
- end
48
+ def order(*values)
49
+ clone.order! values
56
50
  end
57
51
  end
58
52
  end
@@ -17,6 +17,22 @@ module Superstore
17
17
  @where_values = []
18
18
  @order_values = []
19
19
  @id_values = []
20
+
21
+ reset
22
+ end
23
+
24
+ def initialize_copy(other)
25
+ @limit_value = @limit_value.dup if @limit_value
26
+ @select_values = @select_values.dup
27
+ @where_values = @where_values.dup
28
+ @order_values = @order_values.dup
29
+ @id_values = @id_values.dup
30
+ reset
31
+ end
32
+
33
+ def reset
34
+ @records = nil
35
+ @loaded = false
20
36
  end
21
37
 
22
38
  private
@@ -38,6 +54,14 @@ module Superstore
38
54
  end
39
55
  end
40
56
 
57
+ def to_a
58
+ unless @loaded
59
+ @records = select_records
60
+ @loaded = true
61
+ end
62
+ @records
63
+ end
64
+
41
65
  def select_records
42
66
  results = []
43
67
  klass.adapter.select(self) do |key, attributes|
@@ -4,11 +4,11 @@ module Superstore
4
4
  self.attribute_types = {}.with_indifferent_access
5
5
 
6
6
  class << self
7
- def register(name, coder)
8
- attribute_types[name] = coder
7
+ def register(name, type)
8
+ attribute_types[name] = type
9
9
  end
10
10
 
11
- def get_coder(name)
11
+ def get_type_class(name)
12
12
  attribute_types[name]
13
13
  end
14
14
  end