csv_record 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +4 -1
  5. data/README.md +51 -39
  6. data/Rakefile +1 -1
  7. data/csv_record.gemspec +8 -6
  8. data/lib/csv_record.rb +0 -23
  9. data/lib/csv_record/associations.rb +1 -1
  10. data/lib/csv_record/callback.rb +4 -2
  11. data/lib/csv_record/callbacks.rb +21 -19
  12. data/lib/csv_record/{csv_queries/condition.rb → condition.rb} +4 -2
  13. data/lib/csv_record/connector.rb +9 -7
  14. data/lib/csv_record/csv_validations/custom_validation.rb +8 -5
  15. data/lib/csv_record/csv_validations/presence_validation.rb +6 -4
  16. data/lib/csv_record/csv_validations/uniqueness_validation.rb +8 -5
  17. data/lib/csv_record/csv_validations/validations.rb +23 -28
  18. data/lib/csv_record/document.rb +12 -12
  19. data/lib/csv_record/field.rb +6 -4
  20. data/lib/csv_record/fields.rb +45 -0
  21. data/lib/csv_record/helpers.rb +10 -6
  22. data/lib/csv_record/{csv_queries/query.rb → query.rb} +8 -15
  23. data/lib/csv_record/reader.rb +120 -0
  24. data/lib/csv_record/timestamps.rb +4 -2
  25. data/lib/csv_record/version.rb +3 -3
  26. data/lib/csv_record/writer.rb +143 -0
  27. data/test/csv_record/associations_test.rb +1 -1
  28. data/test/csv_record/connector_test.rb +3 -3
  29. data/test/csv_record/reader_test.rb +6 -6
  30. data/test/csv_record/validation_test.rb +1 -1
  31. data/test/models/callback_test_class.rb +1 -2
  32. data/test/models/custom_errors_class.rb +2 -1
  33. data/test/models/customized_class.rb +1 -1
  34. data/test/models/jedi.rb +4 -3
  35. data/test/models/jedi_order.rb +2 -2
  36. data/test/models/padawan.rb +1 -1
  37. data/test/test_helper.rb +3 -3
  38. data/test/{helpers.rb → test_helpers.rb} +2 -2
  39. metadata +80 -52
  40. data/lib/csv_record/csv_fields.rb +0 -45
  41. data/lib/csv_record/csv_readers/class_reader.rb +0 -82
  42. data/lib/csv_record/csv_readers/instance_reader.rb +0 -29
  43. data/lib/csv_record/csv_readers/reader.rb +0 -9
  44. data/lib/csv_record/csv_writers/class_writer.rb +0 -52
  45. data/lib/csv_record/csv_writers/instance_writer.rb +0 -86
  46. data/lib/csv_record/csv_writers/writer.rb +0 -9
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b56ddc51a9bc473b810efc0342ede311cf20fc01
4
+ data.tar.gz: 26a034a21daf07b878aa68ace0668ca689a567e9
5
+ SHA512:
6
+ metadata.gz: 1f849ebfc371659527501acc487df4c0a78d001edb8deb5027c242369bce46aef9cbfd0f7c94265fa8070972d99678204a8243adf59c876545d68032f652acac
7
+ data.tar.gz: 6a934c1164d1ea2605bc4884b82efbe355b210cbb434d772c1a825a2c0a69e9f1873f91f34dd386af94cef2191867bb18bb350d16861f1b8aa9baae8b31e8ecc
@@ -0,0 +1 @@
1
+ csv_record
@@ -0,0 +1 @@
1
+ ruby-2.4.2
@@ -1,5 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.2
4
3
  - 1.9.3
5
4
  - 2.0.0
5
+ - 2.1.0
6
+ - 2.2.9
7
+ - 2.3.6
8
+ - 2.4.3
data/README.md CHANGED
@@ -1,10 +1,14 @@
1
1
  # CsvRecord
2
2
 
3
- [![Build Status](https://travis-ci.org/lukelex/csv_record.png?branch=2.0.0)](https://travis-ci.org/lukelex/csv_record) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/lukelex/csv_record) [![Dependency Status](https://gemnasium.com/lukasalexandre/csv_record.png)](https://gemnasium.com/lukasalexandre/csv_record) [![Gem Version](https://fury-badge.herokuapp.com/rb/csv_record.png)](http://badge.fury.io/rb/csv_record)
3
+ [![Build Status](https://travis-ci.org/lukelex/csv_record.png?branch=2.0.0)](https://travis-ci.org/lukelex/csv_record)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/lukelex/csv_record)
5
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/csv_record.png)](http://badge.fury.io/rb/csv_record)
4
6
 
5
- CSV Record connects Ruby classes to CSV documents database to establish an almost zero-configuration persistence layer for applications.
7
+ CSV Record connects Ruby classes to CSV documents in order to
8
+ establish an almost zero-configuration persistence layer for
9
+ applications.
6
10
 
7
- ##Getting Started
11
+ ## Getting Started
8
12
 
9
13
  Add this line to your application's Gemfile:
10
14
 
@@ -24,7 +28,8 @@ Or install it yourself as:
24
28
  $ gem install csv_record
25
29
  ```
26
30
 
27
- And inside your Ruby models just require and include the CSVRecord lib and start using it in the same way as your are used to:
31
+ And inside your Ruby models just require and include the CSVRecord
32
+ lib and start using it in the same way as your are used to:
28
33
 
29
34
  ```ruby
30
35
  require 'csv_record'
@@ -36,27 +41,28 @@ class Jedi
36
41
  end
37
42
  ```
38
43
 
39
- ##Persistance
40
- To persist the data objects created in your application your can use the following methods:
44
+ ## Persistence
45
+ To persist the data objects created in your application you can
46
+ use the following methods:
41
47
 
42
48
  ```ruby
43
- Jedi.create( # save the new record in the database
49
+ Jedi.create( # save the new record in its CSV file
44
50
  name: 'Luke Skywalker',
45
51
  age: 18,
46
52
  midi_chlorians: '12k'
47
53
  )
48
54
 
49
- jedi.save # save the record in the database (either creating or changing)
55
+ jedi.save # save the record in its CSV file (either creating or changing)
50
56
 
51
57
  jedi.update_attribute :age, 29 # update a single field of an object
52
58
  jedi.update_attributes age: 29, midi_chlorians: '18k' # update multiple fields at the same time
53
59
 
54
- jedi.destroy # removes the record from the database
60
+ jedi.destroy # removes the record from its CSV file
55
61
 
56
62
  jedi.new_record? # checks if the record is new
57
63
  ```
58
64
 
59
- ##Querying
65
+ ## Querying
60
66
  Records can be queried through the following methods:
61
67
 
62
68
  ```ruby
@@ -70,10 +76,10 @@ Jedi.find_by_name_and_age 'Luke Skywalker', 18 # find dynamically with multiple
70
76
 
71
77
  Jedi.where age: 18, name: 'Luke Skywalker', midi_chlorians: '12k' # find with a multiple parameters hash
72
78
 
73
- Jedi.count # returns the amount of records in the database
79
+ Jedi.count # returns the amount of records in its CSV file
74
80
 
75
- Jedi.first # retrieves the first record in the database
76
- Jedi.last # retrieves the last record in the database
81
+ Jedi.first # retrieves the first record in its CSV file
82
+ Jedi.last # retrieves the last record in its CSV file
77
83
  ```
78
84
 
79
85
  Lazy querying is the default behavior now Yey!!
@@ -85,8 +91,8 @@ query # #<CsvRecord::Query:0x007fdff3d31aa0>
85
91
  query.first # #<Jedi:0x007f9df6cea478>
86
92
  ```
87
93
 
88
- ##Associations
89
- ###Belongs To
94
+ ## Associations
95
+ ### Belongs To
90
96
  A Belongs To association can be declared through the following method:
91
97
 
92
98
  ```ruby
@@ -117,7 +123,7 @@ jedi.save
117
123
  jedi.jedi_order # #<JediOrder:0x007f9b249b24d8>
118
124
  ```
119
125
 
120
- ###Has Many
126
+ ### Has Many
121
127
  Extending the previous example, you can use the `has_many` method to establish the inverse relationship:
122
128
 
123
129
  ```ruby
@@ -137,7 +143,7 @@ jedi.save
137
143
  jedi_order.jedis # [#<Jedi:0x007f9b249b24d8>]
138
144
  ```
139
145
 
140
- ###Has One
146
+ ### Has One
141
147
  The same as has_many but limited to one associated record.
142
148
 
143
149
  ```ruby
@@ -164,11 +170,11 @@ jedi.padawan = padawan
164
170
  jedi.padawan # #<Padawan:0x007f9b249b24d8>
165
171
  ```
166
172
 
167
- ##Callbacks
168
- ###Overview
173
+ ## Callbacks
174
+ ### Overview
169
175
  Callbacks can be used to execute code on predetermined moments.
170
176
 
171
- ####Usage
177
+ #### Usage
172
178
  ```ruby
173
179
  after_create do
174
180
  # learn the way of the force
@@ -176,14 +182,14 @@ end
176
182
  ```
177
183
  `self` refers to the instance you are in
178
184
 
179
- ###Avaiable Callbacks
185
+ ### Available Callbacks
180
186
  Here is a list with all the available callbacks, listed in the same order in which they will get called during the respective operations:
181
187
 
182
- ####Finding an Object
188
+ #### Finding an Object
183
189
  * after_initialize
184
190
  * after_find
185
191
 
186
- ####Creating an Object
192
+ #### Creating an Object
187
193
  * after_initialize
188
194
  * before_validation
189
195
  * after_validation
@@ -192,7 +198,7 @@ Here is a list with all the available callbacks, listed in the same order in whi
192
198
  * after_create
193
199
  * after_save
194
200
 
195
- ####Updating an Object
201
+ #### Updating an Object
196
202
  * before_validation
197
203
  * after_validation
198
204
  * before_save
@@ -200,16 +206,16 @@ Here is a list with all the available callbacks, listed in the same order in whi
200
206
  * after_update
201
207
  * after_save
202
208
 
203
- ####Destroying an Object
209
+ #### Destroying an Object
204
210
  * before_destroy
205
211
  * after_destroy
206
212
 
207
- ##Validations
208
- ###Helpers available:
213
+ ## Validations
214
+ ### Helpers available:
209
215
 
210
216
  `validates_presence_of`: Ensures if the specified attribute(s) were filled
211
217
 
212
- `validates_uniqueness_of`: Ensures that the specified attribute(s) are unique within the database
218
+ `validates_uniqueness_of`: Ensures that the specified attribute(s) are unique within its CSV file
213
219
 
214
220
  `validate`: Uses custom method(s) to validate the model
215
221
 
@@ -240,30 +246,36 @@ jedi.invalid? # => true
240
246
  jedi.save # => false
241
247
  ```
242
248
 
243
- ##Customizations
249
+ ## Customizations
244
250
 
245
- Someday you might want to go "out of the rail" that we propose. Here is what you can do now:
251
+ Someday you might want to go "out of the rail" that we propose.
252
+ Here is what you can do now:
246
253
 
247
- ###Changing the table_name
254
+ ### Changing the table_name
248
255
  ```ruby
249
256
  store_as :wierd_table_name
250
257
  ```
251
- ###Changing the field column name
258
+ ### Changing the field column name
252
259
  ```ruby
253
260
  mapping :name => :wierd_field
254
261
  ```
255
262
 
256
- ##Bug reports
263
+ ## Bug reports
257
264
 
258
- If you discover a problem with CSV_Record, we would like to know about it. Please let us know on the project issues page.
265
+ If you discover a problem with CSV_Record, we would like to know
266
+ about it. Please let us know on the project issues page.
259
267
 
260
- ##Contributing
268
+ ## Contributing
261
269
 
262
- We hope that you will consider contributing to CSV_Record. Please read this short overview for some information about how to get started:
270
+ We hope that you will consider contributing to CSV_Record. Please
271
+ read this short overview for some information about how to get started:
263
272
 
264
273
  https://github.com/lukelex/csv_record/wiki/Contributing
265
274
 
266
- You will usually want to write tests for your changes. To run the test suite, go into CSV_Record's top-level directory and run "bundle install" and "rake". For the tests to pass.
275
+ You will usually want to write tests for your changes. To run the
276
+ test suite, go into CSV_Record's top-level directory and run
277
+ "bundle install" and "rake". For the tests to pass.
267
278
 
268
- ##Precautions
269
- CsvRecord creates a `db` folder in the root of your application. Be sure that it has permission to do so.
279
+ ## Precautions
280
+ CsvRecord creates a `db` folder in the root of your application.
281
+ Be sure that it has permission to do so.
data/Rakefile CHANGED
@@ -9,4 +9,4 @@ Rake::TestTask.new do |t|
9
9
  end
10
10
 
11
11
  desc "Run tests"
12
- task default: :test
12
+ task default: :test
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  require File.expand_path('../lib/csv_record/version', __FILE__)
3
2
 
4
3
  Gem::Specification.new do |gem|
@@ -17,10 +16,13 @@ Gem::Specification.new do |gem|
17
16
  gem.require_paths = ["lib"]
18
17
  gem.version = CsvRecord::VERSION
19
18
 
20
- gem.add_dependency 'activesupport', '~> 3.2.9'
19
+ gem.add_dependency 'activesupport', '~> 0'
21
20
 
22
- gem.add_development_dependency 'rake', '~> 0.9.2.2'
23
- gem.add_development_dependency 'timecop', '~> 0.5.3'
24
- gem.add_development_dependency 'turn', '~> 0.9.6'
25
- gem.add_development_dependency 'minitest', '~> 4.3.1'
21
+ gem.add_development_dependency 'rake', '~> 0'
22
+ gem.add_development_dependency 'timecop', '~> 0'
23
+ gem.add_development_dependency 'turn', '~> 0'
24
+ gem.add_development_dependency 'minitest', '~> 0'
25
+ gem.add_development_dependency 'pry', '~> 0'
26
+ gem.add_development_dependency 'pry-nav', '~> 0'
27
+ gem.add_development_dependency 'm', '~> 0'
26
28
  end
@@ -1,26 +1,3 @@
1
- #--
2
- # Copyright (c) 2012 Lukas Alexandre
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
1
  require 'csv'
25
2
 
26
3
  require 'csv_record/version'
@@ -36,4 +36,4 @@ module CsvRecord::Associations
36
36
  end
37
37
  end
38
38
  end
39
- end
39
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CsvRecord::Callback
2
4
  attr_accessor :kind, :code
3
5
 
@@ -7,6 +9,6 @@ class CsvRecord::Callback
7
9
  end
8
10
 
9
11
  def run_on(obj)
10
- obj.instance_eval &self.code
12
+ obj.instance_eval(&self.code)
11
13
  end
12
- end
14
+ end
@@ -1,4 +1,6 @@
1
- require 'csv_record/callback'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'callback'
2
4
 
3
5
  module CsvRecord::Callbacks
4
6
  CALLBACK_TYPES = [
@@ -22,7 +24,7 @@ module CsvRecord::Callbacks
22
24
  const_variable = "#{callback_type}_callbacks".upcase
23
25
  const_set(const_variable, []) unless const_defined? const_variable
24
26
  if block
25
- const_get(const_variable) << (CsvRecord::Callback.new callback_type, block)
27
+ const_get(const_variable) << CsvRecord::Callback.new(callback_type, block)
26
28
  end
27
29
  end
28
30
  end
@@ -35,9 +37,9 @@ module CsvRecord::Callbacks
35
37
  end
36
38
 
37
39
  module InstanceMethods
38
- CALLBACK_TYPES.each do |callback|
39
- define_method "run_#{callback}_callbacks" do
40
- const_variable = "#{callback}_callbacks".upcase
40
+ CALLBACK_TYPES.each do |type|
41
+ define_method "run_#{type}_callbacks" do
42
+ const_variable = "#{type}_callbacks".upcase
41
43
  if self.class.const_defined? const_variable
42
44
  callbacks_collection = self.class.const_get const_variable
43
45
  callbacks_collection.each do |callback|
@@ -49,45 +51,45 @@ module CsvRecord::Callbacks
49
51
 
50
52
  [:build, :initialize].each do |initialize_method|
51
53
  define_method initialize_method do |*args|
52
- result = super *args
53
- self.run_after_initialize_callbacks
54
+ result = super(*args)
55
+ run_after_initialize_callbacks
54
56
  result
55
57
  end
56
58
  end
57
59
 
58
60
  def valid?
59
- self.run_before_validation_callbacks
61
+ run_before_validation_callbacks
60
62
  is_valid = super
61
- self.run_after_validation_callbacks if is_valid
63
+ run_after_validation_callbacks if is_valid
62
64
  is_valid
63
65
  end
64
66
 
65
67
  def destroy
66
- self.run_before_destroy_callbacks
68
+ run_before_destroy_callbacks
67
69
  is_destroyed = super
68
- self.run_after_destroy_callbacks if is_destroyed
70
+ run_after_destroy_callbacks if is_destroyed
69
71
  is_destroyed
70
72
  end
71
73
 
72
74
  def save(*args)
73
- self.run_before_save_callbacks
75
+ run_before_save_callbacks
74
76
  is_saved = super
75
- self.run_after_save_callbacks if is_saved
77
+ run_after_save_callbacks if is_saved
76
78
  is_saved
77
79
  end
78
80
 
79
81
  def append_registry
80
- self.run_before_create_callbacks
82
+ run_before_create_callbacks
81
83
  is_saved = super
82
- self.run_after_create_callbacks if is_saved
84
+ run_after_create_callbacks if is_saved
83
85
  is_saved
84
86
  end
85
87
 
86
88
  def update_registry
87
- self.run_before_update_callbacks
89
+ run_before_update_callbacks
88
90
  saved = super
89
- self.run_after_destroy_callbacks if saved
90
- self.run_after_update_callbacks if saved
91
+ run_after_destroy_callbacks if saved
92
+ run_after_update_callbacks if saved
91
93
  saved
92
94
  end
93
95
  end
@@ -96,4 +98,4 @@ module CsvRecord::Callbacks
96
98
  receiver.extend ClassMethods
97
99
  receiver.send :include, InstanceMethods
98
100
  end
99
- end
101
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CsvRecord::Condition
2
4
  attr_reader :field, :value
3
5
 
@@ -8,11 +10,11 @@ class CsvRecord::Condition
8
10
 
9
11
  def self.create_from_hashes(hashes)
10
12
  hashes.map do |hash|
11
- new *hash
13
+ new(*hash)
12
14
  end
13
15
  end
14
16
 
15
17
  def to_code
16
18
  "attributes['#{@field}'] == '#{@value}'"
17
19
  end
18
- end
20
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CsvRecord::Connector
2
4
  DATABASE_FOLDER = 'db'.freeze
3
5
  APPEND_MODE = 'a'.freeze
@@ -6,7 +8,7 @@ module CsvRecord::Connector
6
8
 
7
9
  # Checks wheter the database directory exists
8
10
  def __initialize_db_directory__
9
- unless Dir.exists? DATABASE_FOLDER
11
+ unless Dir.exist?(DATABASE_FOLDER)
10
12
  Dir.mkdir DATABASE_FOLDER
11
13
  end
12
14
  end
@@ -15,7 +17,7 @@ module CsvRecord::Connector
15
17
  def __initialize_db__
16
18
  __initialize_db_directory__
17
19
  unless db_initialized?
18
- open_database_file WRITE_MODE do |csv|
20
+ open_database_file(WRITE_MODE) do |csv|
19
21
  csv << doppelganger_fields
20
22
  end
21
23
  end
@@ -23,7 +25,7 @@ module CsvRecord::Connector
23
25
 
24
26
  # Checks wheter the database file exists
25
27
  def db_initialized?
26
- File.exist? self.const_get 'DATABASE_LOCATION'
28
+ File.exist? self.const_get('DATABASE_LOCATION')
27
29
  end
28
30
 
29
31
  # Open the database file
@@ -43,7 +45,7 @@ module CsvRecord::Connector
43
45
  CSV.open(self.const_get('DATABASE_LOCATION_TMP'), WRITE_MODE, headers: true) do |copy|
44
46
  copy << fields
45
47
  csv.entries.each do |entry|
46
- new_row = yield entry
48
+ new_row = yield(entry)
47
49
  copy << new_row if new_row
48
50
  end
49
51
  end
@@ -51,13 +53,13 @@ module CsvRecord::Connector
51
53
  rename_database
52
54
  end
53
55
 
54
- protected
56
+ private
55
57
 
56
58
  # Rename the TMP database file to replace the original
57
59
  def rename_database
58
60
  old_file = self.const_get 'DATABASE_LOCATION'
59
61
  tmp_file = self.const_get 'DATABASE_LOCATION_TMP'
60
- while not File.exists?(old_file) ; sleep(10) ; end
62
+ while not File.exist?(old_file) ; sleep(10) ; end
61
63
  File.delete old_file
62
64
  File.rename tmp_file, old_file
63
65
  end
@@ -66,4 +68,4 @@ module CsvRecord::Connector
66
68
  alias :initialize_db :__initialize_db__
67
69
  alias :open_database_file :__open_database_file__
68
70
  alias :parse_database_file :__parse_database_file__
69
- end
71
+ end