less_active_record 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d2876c402d58c9627d363baf670ce5f9390127ca
4
+ data.tar.gz: c6083fe9cb8bc5b5f3aadda9c3872176d2c559cb
5
+ SHA512:
6
+ metadata.gz: d942d268578414b75f3bd0cc132ea27b26713eb8f1a848acda70661f6773821ad700449914768b8ed0e13067742946afd1348925434ac9e72e40f2fa1786b4e4
7
+ data.tar.gz: 4279cd9c36370739f2214991fefb9d465a7fe5f70d9827400412fd352d7d0f182820d61b3f940465c7728b54f09d21e8ade6f649c90c6be5e6010c1794c11cbf
@@ -0,0 +1,19 @@
1
+ module RecordFinders
2
+ def all
3
+ where({})
4
+ end
5
+
6
+ def find(id)
7
+ if record = _adapter.search(id: id).first
8
+ new(record).tap { |item| item.send(:id=, id) }
9
+ else
10
+ raise 'Record not found!'
11
+ end
12
+ end
13
+
14
+ def where(attributes)
15
+ _adapter.search(attributes).map do |record|
16
+ new(record).tap { |item| item.send(:id=, record[:id]) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,66 @@
1
+ require 'less_active_record/yaml_object_mapper'
2
+
3
+ class YAMLAdapter
4
+ attr_reader :file_name
5
+
6
+ def initialize(storage_name)
7
+ @file_name = "#{ storage_name }.yml"
8
+ @_mapper = YAMLObjectMapper.new(file_name)
9
+ end
10
+
11
+ def update(id, attributes)
12
+ item = search(id: id).first
13
+ if item.nil?
14
+ false
15
+ else
16
+ attributes.delete(:id)
17
+ index = _items.index(item)
18
+ _items[index].update(attributes)
19
+
20
+ true
21
+ end
22
+ end
23
+
24
+ def insert(attributes)
25
+ calculate_id.tap do |id|
26
+ _items << attributes.merge(id: id)
27
+ dump_all_items!
28
+ end
29
+ end
30
+
31
+ def destroy(id)
32
+ item = search(id: id).first
33
+ unless item.nil?
34
+ _items.delete(item)
35
+ dump_all_items!
36
+
37
+ item
38
+ end
39
+ end
40
+
41
+ def search(attributes = {})
42
+ _items.map(&:clone).reject do |item|
43
+ attributes.keys.any? { |key| attributes[key] != item[key] }
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ attr_reader :_mapper
50
+
51
+ def _items
52
+ @_items ||= load_all_items || []
53
+ end
54
+
55
+ def load_all_items
56
+ _mapper.load_file
57
+ end
58
+
59
+ def calculate_id
60
+ (_items.map { |item| item[:id] }.max || 0) + 1
61
+ end
62
+
63
+ def dump_all_items!
64
+ _mapper.dump_file(_items)
65
+ end
66
+ end
@@ -0,0 +1,17 @@
1
+ class YAMLObjectMapper
2
+ attr_reader :file_name
3
+
4
+ def initialize(file_name)
5
+ @file_name = file_name
6
+ end
7
+
8
+ def load_file
9
+ YAML.load_file(file_name) if File.exists?(file_name)
10
+ end
11
+
12
+ def dump_file(object)
13
+ File.open(file_name, 'w') do |file|
14
+ YAML.dump(object, file)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,125 @@
1
+ require 'less_active_record/yaml_adapter'
2
+ require 'less_active_record/record_finders'
3
+
4
+ class LessActiveRecord
5
+ extend RecordFinders
6
+
7
+ attr_reader :id
8
+
9
+ class << self
10
+ def create(attributes = {})
11
+ new(attributes).tap(&:save)
12
+ end
13
+
14
+ def storage_name
15
+ "#{ self.to_s }Table"
16
+ end
17
+
18
+ def attribute(name)
19
+ symbolized_name = name.to_sym
20
+ unless attribute_names.include? symbolized_name
21
+ attr_accessor symbolized_name
22
+ self.attribute_names <<= symbolized_name
23
+ end
24
+
25
+ self
26
+ end
27
+
28
+ def attribute_names
29
+ (@attribute_names ||= []).clone
30
+ end
31
+
32
+ def validate(method_name)
33
+ symbolized_name = method_name.to_sym
34
+ unless validations.include? symbolized_name
35
+ self.validations <<= symbolized_name
36
+ end
37
+
38
+ self
39
+ end
40
+
41
+ def validations
42
+ (@validations ||= []).clone
43
+ end
44
+
45
+ protected
46
+
47
+ attr_writer :attribute_names
48
+ attr_writer :validations
49
+
50
+ def _adapter
51
+ @_adapter ||= YAMLAdapter.new(storage_name)
52
+ end
53
+ end
54
+
55
+ def initialize(attributes = {})
56
+ self.attributes = attributes
57
+ end
58
+
59
+ def save
60
+ return false unless valid?
61
+
62
+ if new_record?
63
+ @id = _adapter.insert(attributes)
64
+
65
+ true
66
+ else
67
+ _adapter.update(id, attributes)
68
+ end
69
+ end
70
+
71
+ def update(attributes = {})
72
+ self.attributes = attributes
73
+ save
74
+ end
75
+
76
+ def destroy
77
+ _adapter.destroy(id)
78
+ end
79
+
80
+ def attributes
81
+ self.class.attribute_names.each_with_object({}) do |name, attributes|
82
+ attributes[name] = send(name)
83
+ end
84
+ end
85
+
86
+ def attributes=(attributes)
87
+ self.class.attribute_names.each do |name|
88
+ send("#{ name }=", attributes[name]) if attributes.key?(name)
89
+ end
90
+ end
91
+
92
+ def valid?
93
+ self.class.validations.each do |validation|
94
+ return false unless send(validation)
95
+ end
96
+
97
+ true
98
+ rescue
99
+ false
100
+ end
101
+
102
+ def persisted?
103
+ not new_record?
104
+ end
105
+
106
+ def new_record?
107
+ id.nil?
108
+ end
109
+
110
+ def clone
111
+ self.class.new(attributes).tap { |clone| clone.id = id }
112
+ end
113
+
114
+ def ==(other)
115
+ id == other.id
116
+ end
117
+
118
+ protected
119
+
120
+ attr_writer :id
121
+
122
+ def _adapter
123
+ self.class.send(:_adapter)
124
+ end
125
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: less_active_record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Marius Jašinskas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.3'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 10.3.2
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '10.3'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 10.3.2
47
+ description: |2
48
+ A simple active record mock working with text file (right now YAML)
49
+ databases. It is in no way meant to be used in production code. This
50
+ is just for active record basics learning purposes.
51
+ email: marius.jasinskas@necolt.com
52
+ executables: []
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - lib/less_active_record.rb
57
+ - lib/less_active_record/record_finders.rb
58
+ - lib/less_active_record/yaml_adapter.rb
59
+ - lib/less_active_record/yaml_object_mapper.rb
60
+ homepage: https://github.com/emjei/less_active_record
61
+ licenses:
62
+ - AFL-3.0
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Simplified active record implementation.
84
+ test_files: []
85
+ has_rdoc: