memory_model 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +15 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +7 -4
  4. data/Appraisals +9 -0
  5. data/Guardfile +7 -1
  6. data/README.md +5 -1
  7. data/Rakefile +12 -0
  8. data/gemfiles/rails_3.gemfile +8 -0
  9. data/gemfiles/rails_3.gemfile.lock +109 -0
  10. data/gemfiles/rails_4.gemfile +8 -0
  11. data/gemfiles/rails_4.gemfile.lock +117 -0
  12. data/lib/memory_model/base/actions/class_methods.rb +27 -0
  13. data/lib/memory_model/base/actions.rb +75 -0
  14. data/lib/memory_model/base/attributes.rb +87 -0
  15. data/lib/memory_model/base/auto_increment.rb +47 -0
  16. data/lib/memory_model/base/collectible.rb +26 -0
  17. data/lib/memory_model/base/conversion.rb +11 -0
  18. data/lib/memory_model/base/fields/field.rb +57 -0
  19. data/lib/memory_model/base/fields/field_set.rb +87 -0
  20. data/lib/memory_model/base/fields.rb +49 -0
  21. data/lib/memory_model/base/operations/comparisons.rb +25 -0
  22. data/lib/memory_model/base/operations.rb +10 -0
  23. data/lib/memory_model/base/persistence.rb +13 -11
  24. data/lib/memory_model/base.rb +58 -43
  25. data/lib/memory_model/collection/finders.rb +75 -0
  26. data/lib/memory_model/collection/index/multi.rb +61 -0
  27. data/lib/memory_model/collection/index/unique.rb +79 -0
  28. data/lib/memory_model/collection/index.rb +86 -0
  29. data/lib/memory_model/collection/initializers.rb +48 -0
  30. data/lib/memory_model/collection/loader_delegate.rb +63 -0
  31. data/lib/memory_model/collection/marshaled_record.rb +23 -0
  32. data/lib/memory_model/collection/operations.rb +82 -0
  33. data/lib/memory_model/collection.rb +18 -73
  34. data/lib/memory_model/version.rb +1 -1
  35. data/lib/memory_model.rb +7 -7
  36. data/memory_model.gemspec +8 -3
  37. data/spec/benchmark/benchmark.rb +126 -0
  38. data/spec/memory_model/base/{actionable_spec.rb → actions_spec.rb} +34 -103
  39. data/spec/memory_model/base/{attributable_spec.rb → attributes_spec.rb} +4 -6
  40. data/spec/memory_model/base/{collectable_spec.rb → collectible_spec.rb} +1 -1
  41. data/spec/memory_model/base/fieldable/field_set_spec.rb +23 -37
  42. data/spec/memory_model/base/fieldable/field_spec.rb +16 -16
  43. data/spec/memory_model/base/{fieldable_spec.rb → fields_spec.rb} +1 -1
  44. data/spec/memory_model/base/{comparable_spec.rb → operations/comparisons_spec.rb} +4 -4
  45. data/spec/memory_model/base/persistence_spec.rb +2 -2
  46. data/spec/memory_model/base_spec.rb +10 -9
  47. data/spec/memory_model/collection_spec.rb +24 -146
  48. data/spec/spec_helper.rb +11 -0
  49. data/spec/support/delegate_matcher.rb +40 -0
  50. metadata +120 -65
  51. data/.idea/.rakeTasks +0 -7
  52. data/.idea/dictionaries/jwaldrip.xml +0 -3
  53. data/.idea/encodings.xml +0 -5
  54. data/.idea/memory_model.iml +0 -47
  55. data/.idea/misc.xml +0 -8
  56. data/.idea/modules.xml +0 -9
  57. data/.idea/scopes/scope_settings.xml +0 -5
  58. data/.idea/vcs.xml +0 -7
  59. data/.idea/workspace.xml +0 -701
  60. data/lib/memory_model/base/actionable.rb +0 -95
  61. data/lib/memory_model/base/attributable.rb +0 -76
  62. data/lib/memory_model/base/collectable.rb +0 -22
  63. data/lib/memory_model/base/comparable.rb +0 -16
  64. data/lib/memory_model/base/fieldable/field.rb +0 -35
  65. data/lib/memory_model/base/fieldable/field_set.rb +0 -74
  66. data/lib/memory_model/base/fieldable.rb +0 -45
  67. data/lib/memory_model/base/versionable.rb +0 -17
  68. data/lib/memory_model/core_ext/object.rb +0 -5
  69. data/spec/memory_model/base/versionable_spec.rb +0 -31
  70. data/spec/memory_model/core_ext/object_spec.rb +0 -12
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjIyNWNmNzg5ZDI5ZWU3OGNkY2MyZTg3MWE3Y2FmM2JkYmNlNzkzNQ==
5
+ data.tar.gz: !binary |-
6
+ MDhkNDU2YjhiMzI1MjNhZmZkMTJmMzQxNWIzNDc0MDdjYzVmOTZhYg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ODcwZDk4NTdkZjYyNjRjY2Y0NWY4YTQ0OTMwZjI4NDdjZmRmYTg2NGNkOTVl
10
+ NWIyNzllMWI3ZGI1ZDZjN2IxNDUwMmM1ZmZiMjYzZTI4NDM1MTlmY2VjYWQ0
11
+ YTBiZjgwNjNhOTBjOTZmZjRkZmQzZDU5ZTAwYzM5YmIwNDM4MzA=
12
+ data.tar.gz: !binary |-
13
+ N2U4Y2JiOWYwMDY2NzM3NDgzNWE0NmY2MzdhYjdkNmUxOTQzYTQxMjYxZjZh
14
+ NDlmODNhNTZiZDM5NzY3MWQwZDE3OWYwNTdhNjM3NGEzYjc5NDI3MjAxMjNh
15
+ Y2VkN2I2YjFlZTZmOTdhOWU0MGFlYzAzZDIxNjNmMGQ5NjY2MTI=
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p448
data/.travis.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.3"
4
- - jruby-19mode # JRuby in 1.9 mode
5
- # uncomment this line if your project needs to run something other than `rake`:
6
- script: bundle exec rspec
3
+ - 2.1.0-preview1
4
+ - 2.0.0
5
+ - 1.9.3
6
+
7
+ gemfile:
8
+ - gemfiles/rails_3.gemfile
9
+ - gemfiles/rails_4.gemfile
data/Appraisals ADDED
@@ -0,0 +1,9 @@
1
+ appraise "rails-3" do
2
+ gem "activemodel", "3.2.14"
3
+ gem "activesupport", "3.2.14"
4
+ end
5
+
6
+ appraise "rails-4" do
7
+ gem "activemodel", "4.0.0"
8
+ gem "activesupport", "4.0.0"
9
+ end
data/Guardfile CHANGED
@@ -1,4 +1,10 @@
1
- guard 'rspec', after_all_pass: false, all_on_start: false, cli: '--profile' do
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ # Uncomment next line if Gemfile contain `gemspec' command
4
+ # watch(/^.+\.gemspec/)
5
+ end
6
+
7
+ guard 'rspec', after_all_pass: true, all_on_start: false do
2
8
  watch(%r{^spec/.+_spec\.rb$})
3
9
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
10
  watch('spec/spec_helper.rb') { "spec" }
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- [![Build Status](https://travis-ci.org/jwaldrip/memory_model.png?branch=master)](https://travis-ci.org/jwaldrip/memory_model)
1
+ [![Version](http://allthebadges.io/jwaldrip/memory_model/badge_fury.png)](http://allthebadges.io/jwaldrip/memory_model/badge_fury)
2
+ [![Dependencies](http://allthebadges.io/jwaldrip/memory_model/gemnasium.png)](http://allthebadges.io/jwaldrip/memory_model/gemnasium)
3
+ [![Build Status](http://allthebadges.io/jwaldrip/memory_model/travis.png)](http://allthebadges.io/jwaldrip/memory_model/travis)
4
+ [![Coverage](http://allthebadges.io/jwaldrip/memory_model/coveralls.png)](http://allthebadges.io/jwaldrip/memory_model/coveralls)
5
+ [![Code Climate](http://allthebadges.io/jwaldrip/memory_model/code_climate.png)](http://allthebadges.io/jwaldrip/memory_model/code_climate)
2
6
 
3
7
  # MemoryModel
4
8
 
data/Rakefile CHANGED
@@ -1 +1,13 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
1
3
  require "bundler/gem_tasks"
4
+ require 'appraisal'
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :benchmark do
10
+ require './spec/benchmark/benchmark'
11
+ end
12
+
13
+ task :default => [:spec, :benchmark]
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "3.2.14"
6
+ gem "activesupport", "3.2.14"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,109 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ memory_model (0.0.2)
5
+ activemodel (>= 3.2)
6
+ activesupport (>= 3.2)
7
+ concerned_inheritance
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (3.2.14)
13
+ activesupport (= 3.2.14)
14
+ builder (~> 3.0.0)
15
+ activesupport (3.2.14)
16
+ i18n (~> 0.6, >= 0.6.4)
17
+ multi_json (~> 1.0)
18
+ appraisal (0.5.2)
19
+ bundler
20
+ rake
21
+ builder (3.0.4)
22
+ celluloid (0.15.2)
23
+ timers (~> 1.1.0)
24
+ coderay (1.0.9)
25
+ colorize (0.5.8)
26
+ concerned_inheritance (0.0.2)
27
+ activesupport
28
+ coveralls (0.7.0)
29
+ multi_json (~> 1.3)
30
+ rest-client
31
+ simplecov (>= 0.7)
32
+ term-ansicolor
33
+ thor
34
+ diff-lcs (1.2.4)
35
+ faker (1.2.0)
36
+ i18n (~> 0.5)
37
+ ffi (1.9.0)
38
+ formatador (0.2.4)
39
+ guard (2.0.5)
40
+ formatador (>= 0.2.4)
41
+ listen (~> 2.0)
42
+ lumberjack (~> 1.0)
43
+ pry (>= 0.9.12)
44
+ thor (>= 0.18.1)
45
+ guard-bundler (0.1.3)
46
+ bundler (>= 1.0.0)
47
+ guard (>= 0.2.2)
48
+ guard-rspec (4.0.1)
49
+ guard (~> 2.0)
50
+ rspec (~> 2.14)
51
+ i18n (0.6.5)
52
+ listen (2.1.0)
53
+ celluloid (>= 0.15.2)
54
+ rb-fsevent (>= 0.9.3)
55
+ rb-inotify (>= 0.9)
56
+ lumberjack (1.0.4)
57
+ method_source (0.8.2)
58
+ mime-types (1.25)
59
+ multi_json (1.8.1)
60
+ pry (0.9.12.2)
61
+ coderay (~> 1.0.5)
62
+ method_source (~> 0.8)
63
+ slop (~> 3.4)
64
+ rake (10.1.0)
65
+ rb-fsevent (0.9.3)
66
+ rb-inotify (0.9.2)
67
+ ffi (>= 0.5.0)
68
+ rest-client (1.6.7)
69
+ mime-types (>= 1.16)
70
+ rspec (2.14.1)
71
+ rspec-core (~> 2.14.0)
72
+ rspec-expectations (~> 2.14.0)
73
+ rspec-mocks (~> 2.14.0)
74
+ rspec-core (2.14.5)
75
+ rspec-expectations (2.14.3)
76
+ diff-lcs (>= 1.1.3, < 2.0)
77
+ rspec-mocks (2.14.3)
78
+ simplecov (0.7.1)
79
+ multi_json (~> 1.0)
80
+ simplecov-html (~> 0.7.1)
81
+ simplecov-html (0.7.1)
82
+ slop (3.4.6)
83
+ term-ansicolor (1.2.2)
84
+ tins (~> 0.8)
85
+ terminal-notifier-guard (1.5.3)
86
+ test-unit (2.5.5)
87
+ thor (0.18.1)
88
+ timers (1.1.0)
89
+ tins (0.12.0)
90
+
91
+ PLATFORMS
92
+ ruby
93
+
94
+ DEPENDENCIES
95
+ activemodel (= 3.2.14)
96
+ activesupport (= 3.2.14)
97
+ appraisal
98
+ colorize
99
+ coveralls
100
+ faker
101
+ guard-bundler
102
+ guard-rspec
103
+ memory_model!
104
+ pry
105
+ rb-fsevent
106
+ rspec
107
+ simplecov
108
+ terminal-notifier-guard
109
+ test-unit
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "4.0.0"
6
+ gem "activesupport", "4.0.0"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,117 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ memory_model (0.0.2)
5
+ activemodel (>= 3.2)
6
+ activesupport (>= 3.2)
7
+ concerned_inheritance
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (4.0.0)
13
+ activesupport (= 4.0.0)
14
+ builder (~> 3.1.0)
15
+ activesupport (4.0.0)
16
+ i18n (~> 0.6, >= 0.6.4)
17
+ minitest (~> 4.2)
18
+ multi_json (~> 1.3)
19
+ thread_safe (~> 0.1)
20
+ tzinfo (~> 0.3.37)
21
+ appraisal (0.5.2)
22
+ bundler
23
+ rake
24
+ atomic (1.1.14)
25
+ builder (3.1.4)
26
+ celluloid (0.15.2)
27
+ timers (~> 1.1.0)
28
+ coderay (1.0.9)
29
+ colorize (0.5.8)
30
+ concerned_inheritance (0.0.2)
31
+ activesupport
32
+ coveralls (0.7.0)
33
+ multi_json (~> 1.3)
34
+ rest-client
35
+ simplecov (>= 0.7)
36
+ term-ansicolor
37
+ thor
38
+ diff-lcs (1.2.4)
39
+ faker (1.2.0)
40
+ i18n (~> 0.5)
41
+ ffi (1.9.0)
42
+ formatador (0.2.4)
43
+ guard (2.0.5)
44
+ formatador (>= 0.2.4)
45
+ listen (~> 2.0)
46
+ lumberjack (~> 1.0)
47
+ pry (>= 0.9.12)
48
+ thor (>= 0.18.1)
49
+ guard-bundler (0.1.3)
50
+ bundler (>= 1.0.0)
51
+ guard (>= 0.2.2)
52
+ guard-rspec (4.0.1)
53
+ guard (~> 2.0)
54
+ rspec (~> 2.14)
55
+ i18n (0.6.5)
56
+ listen (2.1.0)
57
+ celluloid (>= 0.15.2)
58
+ rb-fsevent (>= 0.9.3)
59
+ rb-inotify (>= 0.9)
60
+ lumberjack (1.0.4)
61
+ method_source (0.8.2)
62
+ mime-types (1.25)
63
+ minitest (4.7.5)
64
+ multi_json (1.8.1)
65
+ pry (0.9.12.2)
66
+ coderay (~> 1.0.5)
67
+ method_source (~> 0.8)
68
+ slop (~> 3.4)
69
+ rake (10.1.0)
70
+ rb-fsevent (0.9.3)
71
+ rb-inotify (0.9.2)
72
+ ffi (>= 0.5.0)
73
+ rest-client (1.6.7)
74
+ mime-types (>= 1.16)
75
+ rspec (2.14.1)
76
+ rspec-core (~> 2.14.0)
77
+ rspec-expectations (~> 2.14.0)
78
+ rspec-mocks (~> 2.14.0)
79
+ rspec-core (2.14.5)
80
+ rspec-expectations (2.14.3)
81
+ diff-lcs (>= 1.1.3, < 2.0)
82
+ rspec-mocks (2.14.3)
83
+ simplecov (0.7.1)
84
+ multi_json (~> 1.0)
85
+ simplecov-html (~> 0.7.1)
86
+ simplecov-html (0.7.1)
87
+ slop (3.4.6)
88
+ term-ansicolor (1.2.2)
89
+ tins (~> 0.8)
90
+ terminal-notifier-guard (1.5.3)
91
+ test-unit (2.5.5)
92
+ thor (0.18.1)
93
+ thread_safe (0.1.3)
94
+ atomic
95
+ timers (1.1.0)
96
+ tins (0.12.0)
97
+ tzinfo (0.3.38)
98
+
99
+ PLATFORMS
100
+ ruby
101
+
102
+ DEPENDENCIES
103
+ activemodel (= 4.0.0)
104
+ activesupport (= 4.0.0)
105
+ appraisal
106
+ colorize
107
+ coveralls
108
+ faker
109
+ guard-bundler
110
+ guard-rspec
111
+ memory_model!
112
+ pry
113
+ rb-fsevent
114
+ rspec
115
+ simplecov
116
+ terminal-notifier-guard
117
+ test-unit
@@ -0,0 +1,27 @@
1
+ module MemoryModel
2
+ class Base
3
+ module Actions
4
+ module ClassMethods
5
+
6
+ def create(attributes={})
7
+ new(attributes).tap(&:save)
8
+ end
9
+
10
+ def create!(attributes={})
11
+ new(attributes).tap(&:save!)
12
+ end
13
+
14
+ def delete_all
15
+ count.tap do
16
+ self.collection.clear
17
+ end
18
+ end
19
+
20
+ def destroy_all
21
+ self.all.each(&:destroy)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,75 @@
1
+ module MemoryModel
2
+
3
+ class RecordInvalid < MemoryModel::Error
4
+ attr_reader :record # :nodoc:
5
+ def initialize(record) # :nodoc:
6
+ @record = record
7
+ errors = @record.errors.full_messages.join(", ")
8
+ super(errors)
9
+ end
10
+ end
11
+
12
+ class Base
13
+ module Actions
14
+ extend ActiveSupport::Concern
15
+ extend ActiveSupport::Autoload
16
+
17
+ autoload :ClassMethods
18
+
19
+ included do
20
+ define_model_callbacks :create, :update, :save, :destroy, :validation
21
+ define_model_callbacks :commit, only: :after
22
+ before_save(:remove_invalid_instance_vars)
23
+ end
24
+
25
+ VALID_IVARS = [
26
+ :@attributes
27
+ ]
28
+
29
+ def delete
30
+ self.class.collection.delete(self)
31
+ freeze
32
+ end
33
+
34
+ def destroy
35
+ run_callbacks :destroy do
36
+ delete
37
+ end
38
+ end
39
+
40
+ def save(options={})
41
+ !!perform_validations(options) ? commit : false
42
+ end
43
+
44
+ def save!(options={})
45
+ !!perform_validations(options) ? commit : raise(RecordInvalid.new(self))
46
+ end
47
+
48
+ private
49
+
50
+ def commit
51
+ operation = persisted? ? :update : :create
52
+ run_callbacks operation do
53
+ run_callbacks :save do
54
+ self.class.collection.send(operation, self)
55
+ run_callbacks :commit
56
+ end
57
+ end
58
+ self
59
+ end
60
+
61
+ def remove_invalid_instance_vars
62
+ instance_variables.reject { |ivar| ivar.in? VALID_IVARS }.each do |ivar|
63
+ remove_instance_variable ivar if instance_variable_defined?(ivar)
64
+ end
65
+ end
66
+
67
+ def perform_validations(options={})
68
+ run_callbacks :validation do
69
+ options[:validate] == false || valid?(options[:context])
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,87 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+ require 'active_support/core_ext/hash/indifferent_access'
3
+ require 'active_support/hash_with_indifferent_access'
4
+
5
+ module MemoryModel
6
+ class Base
7
+ module Attributes
8
+ extend ActiveSupport::Concern
9
+ include ActiveModel::AttributeMethods
10
+ include ActiveModel::Dirty
11
+
12
+ included do
13
+ delegate :to_hash, to: :attributes
14
+ attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
15
+ attribute_method_prefix 'clear_'
16
+ end
17
+
18
+ def attributes
19
+ @attributes ||= HashWithIndifferentAccess.new
20
+ end
21
+
22
+ def attributes=(hash)
23
+ hash.reduce({}) do |hash, (attr, value)|
24
+ hash.merge attr => write_attribute(attr, value)
25
+ end
26
+ end
27
+
28
+ def has_attribute?(key)
29
+ case value = @attributes[key]
30
+ when NilClass, String
31
+ !value.nil?
32
+ else
33
+ value.present?
34
+ end
35
+ end
36
+
37
+ def inspect
38
+ inspection = fields.reduce([]) { |array, field|
39
+ name = field.name
40
+ array << "#{name}: #{attribute_for_inspect(name)}" if has_attribute?(name)
41
+ array
42
+ }.join(", ")
43
+ inspection = ' ' + inspection if inspection.present?
44
+ super.sub /^(#<[a-z:0-9]+).*>/i, "\\1#{inspection}>"
45
+ end
46
+
47
+ def read_attribute(name)
48
+ attributes[name]
49
+ end
50
+
51
+ alias :[] :read_attribute
52
+
53
+ def write_attribute(name, value)
54
+ raise InvalidFieldError, name unless fields.include? name
55
+ raise ReadOnlyFieldError, name if fields[name].options[:readonly] && persisted?
56
+
57
+ send "#{name}_will_change!" unless value == read_attribute(name) || new_record?
58
+ attributes[name] = value
59
+ end
60
+
61
+ alias :[]= :write_attribute
62
+
63
+ protected
64
+
65
+ def attribute_for_inspect(attr_name)
66
+ value = read_attribute(attr_name)
67
+
68
+ if value.is_a?(String) && value.length > 50
69
+ "#{value[0..50]}...".inspect
70
+ elsif value.is_a?(Date) || value.is_a?(Time)
71
+ value.to_s
72
+ else
73
+ value.inspect
74
+ end
75
+ end
76
+
77
+ def clear_attribute(attr)
78
+ write_attribute attr, nil
79
+ end
80
+
81
+ def reset_attribute_to_default!(attr)
82
+ fields.set_default_value(self, attr)
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,47 @@
1
+ module MemoryModel
2
+ class Base
3
+ module AutoIncrement
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_create(:auto_increment_fields!)
9
+ end
10
+
11
+ private
12
+
13
+ def auto_increment_fields!
14
+ fields.select { |field| field.options[:auto_increment] === true }.each do |field|
15
+ write_attribute(field.name, self.class.auto_increment_for!(field.name))
16
+ end
17
+ end
18
+
19
+ def reset_incremented_fields!
20
+ fields.select { |field| field.options[:auto_increment] === true }.each do |field|
21
+ clear_attribute(field.name)
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+
27
+ def auto_increment_for!(field)
28
+ fields[field].increment!
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ module Fields
36
+ class Field
37
+
38
+ def increment!
39
+ raise ArguementError, "#{name} is not incrementable" unless options[:auto_increment] === true
40
+ @incrementor ||= 0
41
+ @incrementor += 1
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ module MemoryModel
5
+ class Base
6
+ module Collectible
7
+ extend ActiveSupport::Concern
8
+ extend ConcernedInheritance
9
+
10
+ inherited do
11
+ instance_variable_set :@collection, baseclass.collection
12
+ end
13
+
14
+ module ClassMethods
15
+ delegate *(MemoryModel::Collection.instance_methods - Object.instance_methods), to: :collection
16
+ delegate :first, :last, to: :all
17
+
18
+ def collection
19
+ return nil if self == MemoryModel::Base
20
+ @collection ||= MemoryModel::Collection.new(self)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module MemoryModel
2
+ class Base
3
+ module Conversion
4
+
5
+ def to_key
6
+ persisted? ? [id] : nil
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ module MemoryModel
2
+
3
+ class InvalidFieldError < Error
4
+
5
+ def initialize(name)
6
+ super("`#{name}` is not a valid field")
7
+ end
8
+
9
+ end
10
+
11
+ class ReadOnlyFieldError < Error
12
+
13
+ def initialize(name)
14
+ super("`#{name}` is read only")
15
+ end
16
+
17
+ end
18
+
19
+ class Base
20
+ module Fields
21
+ class Field
22
+
23
+ attr_reader :name, :options
24
+
25
+ def initialize(name, options={})
26
+ @name = name.to_sym
27
+ @options = options.reverse_merge!({ readonly: false, comparable: true })
28
+ end
29
+
30
+ def ==(other_object)
31
+ self.to_sym == other_object.to_sym
32
+ end
33
+
34
+ def comparable?
35
+ !!@options[:comparable]
36
+ end
37
+
38
+ def default
39
+ @options[:default]
40
+ end
41
+
42
+ def readonly?
43
+ !!@options[:readonly]
44
+ end
45
+
46
+ def to_sym
47
+ @name.to_sym
48
+ end
49
+
50
+ def to_s
51
+ @name.to_s
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+ end