sheets_db 0.11.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdf056137eb54d33c6647240ada1498ca2527d44fe68dd8f170882ecff233725
4
- data.tar.gz: 61d76eff207e4d88bbad700ea9be592dbdbac4a2d709a1883c53dbeae055790e
3
+ metadata.gz: a6eb0913dc274c00619b8de23c709d73676e64e233294469c00c2eb549afcfbb
4
+ data.tar.gz: ffeaa1616416edd4fa9529c982fce59f39594ec27b6d43eb7da16c5c086824cb
5
5
  SHA512:
6
- metadata.gz: a589ac3ae9d86b63b65691d12ef212323f1ea9266bb8e2230b67972781ba0ca5ec812f3befc0341f67261e16e70fb1511bce37103583ee452869fef1df7bc24b
7
- data.tar.gz: a71d6cf51c4795e6d4185e27c37a0dadf51ea2ec8fdf55607586e510e3a437723f508a20ed7c52fb50373c98c08e8c0cfa74289b5b3da40414241a0079c520f0
6
+ metadata.gz: 06d3c6c10ed9009cfd370de72fd9afc8b4393b77512149fa6043a04c787086822b9c5fd165f21666c3c6612417a77c279ea6fa2023046b6a565dfe7532264f30
7
+ data.tar.gz: 73b8d7c1d5a7b79061af23414984597a66d1e2accf9e7a59c84a8e58e7e53726e66869dc258f60a74b036993156f14c889583be95cf8eb2f8e18176705113edf
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.
1
+ 3.1.
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.call("routing/#{m[1]}_routing"),
51
+ rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ rspec.spec.call("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
@@ -1,18 +1,63 @@
1
1
  module SheetsDB
2
2
  class Collection < Resource
3
+ class SpreadsheetNotFoundError < Resource::ChildResourceNotFoundError; end
4
+
3
5
  set_resource_type GoogleDrive::Collection
4
6
 
5
- def self.has_many(resource, class_name:, resource_type: :subcollections)
6
- unless [:subcollections, :spreadsheets].include?(resource_type)
7
- raise ArgumentError, "resource_type must be :subcollections or :spreadsheets"
7
+ class << self
8
+ def has_many(resource, class_name:, resource_type: :subcollections)
9
+ unless [:subcollections, :spreadsheets].include?(resource_type)
10
+ raise ArgumentError, "resource_type must be :subcollections or :spreadsheets"
11
+ end
12
+ register_association(resource, class_name: class_name, resource_type: resource_type)
13
+ define_method(resource) do
14
+ @associated_resources ||= {}
15
+ @associated_resources[resource] ||= google_drive_resource.send(resource_type).map { |raw|
16
+ Support.constantize(class_name).new(raw)
17
+ }
18
+ end
8
19
  end
9
- register_association(resource, class_name: class_name, resource_type: resource_type)
10
- define_method(resource) do
11
- result = instance_variable_get(:"@#{resource}")
12
- result || instance_variable_set(:"@#{resource}",
13
- google_drive_resource.send(resource_type).map { |raw| Support.constantize(class_name).new(raw) }
14
- )
20
+ end
21
+
22
+ %i[
23
+ spreadsheet
24
+ subcollection
25
+ ].each do |child_resource_type|
26
+ define_method :"google_drive_#{child_resource_type}_by_title" do |title, **kwargs|
27
+ find_child_google_drive_resource_by(type: child_resource_type, title: title, **kwargs)
15
28
  end
16
29
  end
30
+
31
+ def find_spreadsheet(title:)
32
+ find_spreadsheet!(title: title)
33
+ rescue ChildResourceNotFoundError
34
+ nil
35
+ end
36
+
37
+ def find_spreadsheet!(title:)
38
+ find_and_wrap_spreadsheet!(title: title, create: false)
39
+ end
40
+
41
+ def find_or_create_spreadsheet!(title:)
42
+ find_and_wrap_spreadsheet!(title: title, create: true)
43
+ end
44
+
45
+ def find_and_wrap_spreadsheet!(title:, create: false)
46
+ Spreadsheet.new(google_drive_spreadsheet_by_title(title, create: create))
47
+ rescue ChildResourceNotFoundError
48
+ raise SpreadsheetNotFoundError
49
+ end
50
+
51
+ def spreadsheets
52
+ @anonymous_resources ||= {}
53
+ @anonymous_resources[:spreadsheets] ||=
54
+ google_drive_resource.spreadsheets.map { |raw| Spreadsheet.new(raw) }
55
+ end
56
+
57
+ def collections
58
+ @anonymous_resources ||= {}
59
+ @anonymous_resources[:collections] ||=
60
+ google_drive_resource.subcollections.map { |raw| Collection.new(raw) }
61
+ end
17
62
  end
18
- end
63
+ end
@@ -2,6 +2,7 @@ module SheetsDB
2
2
  class Resource
3
3
  class ResourceTypeMismatchError < StandardError; end
4
4
  class CollectionTypeAlreadyRegisteredError < StandardError; end
5
+ class ChildResourceNotFoundError < StandardError; end
5
6
 
6
7
  class << self
7
8
  attr_reader :resource_type
@@ -17,8 +18,8 @@ module SheetsDB
17
18
 
18
19
  def find_by_id(id, session: SheetsDB::Session.default)
19
20
  google_drive_resource = session.raw_file_by_id(id)
20
- if @resource_type && !google_drive_resource.is_a?(@resource_type)
21
- fail(ResourceTypeMismatchError, "The file with id #{id} is not a #{@resource_type}")
21
+ if resource_type && !google_drive_resource.is_a?(resource_type)
22
+ fail(ResourceTypeMismatchError, "The file with id #{id} is not a #{resource_type}")
22
23
  end
23
24
  new(google_drive_resource)
24
25
  end
@@ -26,10 +27,10 @@ module SheetsDB
26
27
  def belongs_to_many(resource, class_name:)
27
28
  register_association(resource, class_name: class_name, resource_type: :parents)
28
29
  define_method(resource) do
29
- result = instance_variable_get(:"@#{resource}")
30
- result || instance_variable_set(:"@#{resource}",
31
- google_drive_resource.parents.map { |id| Support.constantize(class_name).find_by_id(id) }
32
- )
30
+ @associated_resources ||= {}
31
+ @associated_resources[resource] ||= google_drive_resource.parents.map { |id|
32
+ Support.constantize(class_name).find_by_id(id)
33
+ }
33
34
  end
34
35
  end
35
36
 
@@ -43,6 +44,15 @@ module SheetsDB
43
44
  class_name: class_name
44
45
  }
45
46
  end
47
+
48
+ def association_methods_for_type(type)
49
+ raise ArgumentError unless %i[spreadsheet worksheet subcollection].include?(type)
50
+
51
+ google_type = type == :spreadsheet ? :file : type
52
+ create_prefix = type == :worksheet ? :add : :create
53
+
54
+ OpenStruct.new(find: :"#{google_type}_by_title", create: :"#{create_prefix}_#{type}")
55
+ end
46
56
  end
47
57
 
48
58
  extend Forwardable
@@ -56,6 +66,16 @@ module SheetsDB
56
66
  @google_drive_resource = google_drive_resource
57
67
  end
58
68
 
69
+ def reload!
70
+ @associated_resources = nil
71
+ @anonymous_resources = nil
72
+ google_drive_resource.reload_metadata
73
+ end
74
+
75
+ def delete!
76
+ google_drive_resource.delete
77
+ end
78
+
59
79
  def ==(other)
60
80
  other.is_a?(self.class) &&
61
81
  other.google_drive_resource == google_drive_resource
@@ -75,5 +95,14 @@ module SheetsDB
75
95
  updated_at: updated_at
76
96
  }
77
97
  end
98
+
99
+ def find_child_google_drive_resource_by(type:, title:, create: false)
100
+ association_methods = self.class.association_methods_for_type(type)
101
+ child_resource = google_drive_resource.public_send(association_methods.find, title)
102
+ child_resource ||= google_drive_resource.public_send(association_methods.create, title) if create
103
+ raise ChildResourceNotFoundError, [self, type, title] if child_resource.nil?
104
+
105
+ child_resource
106
+ end
78
107
  end
79
108
  end
@@ -1,37 +1,31 @@
1
1
  module SheetsDB
2
2
  class Spreadsheet < Resource
3
3
  class WorksheetAssociationAlreadyRegisteredError < StandardError; end
4
- class WorksheetNotFoundError < StandardError; end
4
+ class WorksheetNotFoundError < Resource::ChildResourceNotFoundError; end
5
+ class LastWorksheetCannotBeDeletedError < StandardError; end
5
6
 
6
7
  set_resource_type GoogleDrive::Spreadsheet
7
8
 
8
- def self.has_many(resource, worksheet_name:, class_name:)
9
- register_worksheet_association(resource, worksheet_name: worksheet_name, class_name: class_name)
10
- create_worksheet_association(resource, worksheet_name: worksheet_name, class_name: class_name)
11
- end
9
+ class << self
10
+ def has_many(resource, worksheet_name:, class_name:)
11
+ register_worksheet_association(resource, worksheet_name: worksheet_name, class_name: class_name)
12
+ create_worksheet_association(resource, worksheet_name: worksheet_name, class_name: class_name)
13
+ end
12
14
 
13
- def self.register_worksheet_association(resource, worksheet_name:, class_name:)
14
- @associations ||= {}
15
- if @associations.fetch(resource, nil)
16
- raise WorksheetAssociationAlreadyRegisteredError
15
+ def register_worksheet_association(resource, worksheet_name:, class_name:)
16
+ @associations ||= {}
17
+ if @associations.fetch(resource, nil)
18
+ raise WorksheetAssociationAlreadyRegisteredError
19
+ end
20
+ @associations[resource] = {
21
+ worksheet_name: worksheet_name,
22
+ class_name: class_name
23
+ }
17
24
  end
18
- @associations[resource] = {
19
- worksheet_name: worksheet_name,
20
- class_name: class_name
21
- }
22
- end
23
25
 
24
- def self.create_worksheet_association(resource, worksheet_name:, class_name:)
25
- define_method(resource) do
26
- @worksheets ||= {}
27
- @worksheets[resource] ||= begin
28
- google_drive_worksheet = google_drive_resource.worksheet_by_title(worksheet_name)
29
- raise WorksheetNotFoundError, worksheet_name if google_drive_worksheet.nil?
30
- Worksheet.new(
31
- spreadsheet: self,
32
- google_drive_resource: google_drive_worksheet,
33
- type: Support.constantize(class_name)
34
- )
26
+ def create_worksheet_association(resource, **kwargs)
27
+ define_method(resource) do
28
+ worksheet_association(resource, **kwargs)
35
29
  end
36
30
  end
37
31
  end
@@ -51,5 +45,65 @@ module SheetsDB
51
45
  def select_from_association(association_name, &block)
52
46
  send(association_name).select(&block)
53
47
  end
48
+
49
+ def worksheet_association(association_name, worksheet_name:, class_name:)
50
+ @associated_resources ||= {}
51
+ @associated_resources[association_name] ||=
52
+ find_or_create_worksheet!(title: worksheet_name, type: Support.constantize(class_name))
53
+ end
54
+
55
+ def worksheets
56
+ @anonymous_resources ||= {}
57
+ @anonymous_resources[:worksheets] ||= google_drive_resource.worksheets.map { |raw|
58
+ set_up_worksheet!(google_drive_resource: raw)
59
+ }
60
+ end
61
+
62
+ def set_up_worksheet!(google_drive_resource:, type: nil)
63
+ wrap_worksheet(google_drive_resource: google_drive_resource, type: type).set_up!
64
+ end
65
+
66
+ def wrap_worksheet(google_drive_resource:, type: nil)
67
+ Worksheet.new(
68
+ google_drive_resource: google_drive_resource,
69
+ spreadsheet: self,
70
+ type: type
71
+ )
72
+ end
73
+
74
+ def find_worksheet(title:, type: nil)
75
+ find_worksheet!(title: title, type: type)
76
+ rescue WorksheetNotFoundError
77
+ nil
78
+ end
79
+
80
+ def find_worksheet!(title:, type: nil)
81
+ find_and_setup_worksheet!(title: title, type: type, create: false)
82
+ end
83
+
84
+ def find_or_create_worksheet!(title:, type: nil)
85
+ find_and_setup_worksheet!(title: title, type: type, create: true)
86
+ end
87
+
88
+ def find_and_setup_worksheet!(title:, type: nil, create: false)
89
+ resource = google_drive_worksheet_by_title(title, create: create)
90
+ set_up_worksheet!(google_drive_resource: resource, type: type)
91
+ rescue ChildResourceNotFoundError
92
+ raise WorksheetNotFoundError
93
+ end
94
+
95
+ def clean_up_default_worksheet!(force: false)
96
+ default_sheet = google_drive_resource.worksheet_by_title("Sheet1")
97
+ return unless default_sheet
98
+
99
+ raise LastWorksheetCannotBeDeletedError if google_drive_resource.worksheets.count == 1
100
+
101
+ wrap_worksheet(google_drive_resource: default_sheet).
102
+ delete_google_drive_resource!(force: force)
103
+ end
104
+
105
+ def google_drive_worksheet_by_title(title, **kwargs)
106
+ find_child_google_drive_resource_by(type: :worksheet, title: title, **kwargs)
107
+ end
54
108
  end
55
109
  end
@@ -1,3 +1,3 @@
1
1
  module SheetsDB
2
- VERSION = "0.11.0"
2
+ VERSION = "0.13.0"
3
3
  end
@@ -172,6 +172,7 @@ module SheetsDB
172
172
  def reload!
173
173
  worksheet.reload!
174
174
  reset_attributes_and_associations_cache
175
+ self
175
176
  end
176
177
 
177
178
  def save!
@@ -179,6 +180,7 @@ module SheetsDB
179
180
  worksheet.update_attributes_at_row_position(staged_attributes, row_position: row_position)
180
181
  save_changed_foreign_items!
181
182
  reset_attributes_and_associations_cache
183
+ self
182
184
  end
183
185
 
184
186
  def assign_next_row_position_if_not_set
@@ -192,6 +194,7 @@ module SheetsDB
192
194
  def reset_attributes_and_associations_cache
193
195
  @loaded_attributes = {}
194
196
  @loaded_associations = {}
197
+ self
195
198
  end
196
199
 
197
200
  def staged_attributes
@@ -1,21 +1,44 @@
1
+ require 'bigdecimal/util'
1
2
  require_relative "worksheet/column"
2
3
  require_relative "worksheet/row"
3
4
 
4
5
  module SheetsDB
5
6
  class Worksheet
6
7
  class ColumnNotFoundError < StandardError; end
8
+ class WorksheetContainsDataError < StandardError; end
7
9
 
8
10
  include Enumerable
11
+ extend Forwardable
9
12
 
10
- attr_reader :spreadsheet, :google_drive_resource, :type, :synchronizing
13
+ attr_reader :spreadsheet, :google_drive_resource, :synchronizing
11
14
 
12
- def initialize(spreadsheet:, google_drive_resource:, type:)
15
+ def_delegator :google_drive_resource, :title
16
+
17
+ def initialize(spreadsheet:, google_drive_resource:, type: nil)
13
18
  @spreadsheet = spreadsheet
14
19
  @google_drive_resource = google_drive_resource
15
20
  @type = type
16
21
  @synchronizing = true
17
22
  end
18
23
 
24
+ def set_up!
25
+ if google_drive_resource.num_rows == 0
26
+ registered_column_names = attribute_definitions.map { |name, definition| definition[:column_name] }
27
+ write_matrix!([registered_column_names])
28
+ end
29
+ self
30
+ end
31
+
32
+ def type
33
+ @type || @generated_type ||= begin
34
+ Class.new(Row).tap { |generated_type_class|
35
+ column_names.each do |name|
36
+ generated_type_class.attribute name.to_sym
37
+ end
38
+ }
39
+ end
40
+ end
41
+
19
42
  def ==(other)
20
43
  other.is_a?(self.class) &&
21
44
  other.google_drive_resource == google_drive_resource &&
@@ -31,7 +54,8 @@ module SheetsDB
31
54
  def columns
32
55
  @columns ||= begin
33
56
  {}.tap { |directory|
34
- google_drive_resource.rows.first.each_with_index do |name, i|
57
+ header_row = google_drive_resource.rows.first || []
58
+ header_row.each_with_index do |name, i|
35
59
  unless name == ""
36
60
  directory[name] = Column.new(name: name, column_position: i + 1)
37
61
  end
@@ -98,12 +122,20 @@ module SheetsDB
98
122
 
99
123
  def update_attributes_at_row_position(staged_attributes, row_position:)
100
124
  staged_attributes.each do |attribute_name, value|
101
- attribute_definition, column = get_definition_and_column(attribute_name)
102
- raise ColumnNotFoundError, column unless column
103
- assignment_value = attribute_definition[:multiple] ? value.join(",") : value
104
- google_drive_resource[row_position, column.column_position] = assignment_value
125
+ update_attribute_at_row_position(
126
+ attribute_name: attribute_name,
127
+ value: value,
128
+ row_position: row_position
129
+ )
105
130
  end
106
- google_drive_resource.synchronize if synchronizing
131
+ synchronize! if synchronizing
132
+ end
133
+
134
+ def update_attribute_at_row_position(attribute_name:, value:, row_position:)
135
+ attribute_definition, column = get_definition_and_column(attribute_name)
136
+ raise ColumnNotFoundError, column unless column
137
+ assignment_value = attribute_definition[:multiple] ? value.join(",") : value
138
+ google_drive_resource[row_position, column.column_position] = assignment_value
107
139
  end
108
140
 
109
141
  def next_available_row_position
@@ -163,7 +195,11 @@ module SheetsDB
163
195
  end
164
196
 
165
197
  def reload!
198
+ @columns = nil
199
+ @existing_raw_data = nil
200
+ @generated_type = nil
166
201
  google_drive_resource.reload
202
+ self
167
203
  end
168
204
 
169
205
  def convert_to_boolean(raw_value)
@@ -180,8 +216,8 @@ module SheetsDB
180
216
  converted_value = case attribute_definition[:type].to_s
181
217
  when "Integer"
182
218
  raw_value.to_i
183
- when "Float"
184
- raw_value.to_f
219
+ when "Decimal"
220
+ raw_value.to_d
185
221
  when "DateTime"
186
222
  DateTime.strptime(raw_value, "%m/%d/%Y %H:%M:%S")
187
223
  when "Boolean"
@@ -205,9 +241,66 @@ module SheetsDB
205
241
  def transaction
206
242
  disable_synchronization!
207
243
  yield
208
- google_drive_resource.synchronize
244
+ synchronize!
209
245
  ensure
210
246
  enable_synchronization!
211
247
  end
248
+
249
+ def delete_google_drive_resource!(force: false)
250
+ raise WorksheetContainsDataError if google_drive_resource.num_rows.nonzero? && !force
251
+
252
+ google_drive_resource.delete
253
+ @google_drive_resource = nil
254
+ spreadsheet.reload!
255
+ end
256
+
257
+ def truncate!
258
+ clear_google_drive_resource!
259
+ set_up!
260
+ reload!
261
+ end
262
+
263
+ def write_matrix(matrix, rewrite: false, save: false)
264
+ clear_google_drive_resource if rewrite
265
+ google_drive_resource.update_cells(1, 1, matrix)
266
+ synchronize! if save
267
+ self
268
+ end
269
+
270
+ def write_matrix!(matrix, **options)
271
+ write_matrix(matrix, **options.merge(save: true))
272
+ end
273
+
274
+ def write_raw_data(data, **options)
275
+ raise ArgumentError, "mismatched keys" if data.map(&:keys).uniq.count > 1
276
+
277
+ write_matrix(data.map(&:values).prepend(data.first.keys), **options)
278
+ end
279
+
280
+ def write_raw_data!(data, **options)
281
+ write_raw_data(data, **options.merge(save: true))
282
+ end
283
+
284
+ def clear_google_drive_resource(save: false)
285
+ empty_matrix = Array.new(google_drive_resource.num_rows, Array.new(google_drive_resource.num_cols))
286
+ write_matrix(empty_matrix, save: save)
287
+ end
288
+
289
+ def clear_google_drive_resource!
290
+ clear_google_drive_resource(save: true)
291
+ end
292
+
293
+ def synchronize!
294
+ google_drive_resource.synchronize
295
+ @existing_raw_data = nil
296
+ self
297
+ end
298
+
299
+ def existing_raw_data
300
+ @existing_raw_data ||= begin
301
+ rows = google_drive_resource.rows
302
+ rows.drop(1).map { |row| Hash[rows.first.zip(row)] }
303
+ end
304
+ end
212
305
  end
213
306
  end
data/sheets_db.gemspec CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "google_drive", "~> 3.0"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 2.1"
23
+ spec.add_development_dependency "bundler", "~> 2.4"
24
24
  spec.add_development_dependency "rake", "~> 13"
25
- spec.add_development_dependency "rspec", "~> 3.10"
25
+ spec.add_development_dependency "rspec", "~> 3.11"
26
26
  spec.add_development_dependency "simplecov"
27
+ spec.add_development_dependency "guard-rspec"
27
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sheets_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Gadad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-17 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google_drive
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.1'
33
+ version: '2.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.1'
40
+ version: '2.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.10'
61
+ version: '3.11'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.10'
68
+ version: '3.11'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description:
84
98
  email:
85
99
  - ravi@ablschools.com
@@ -93,6 +107,7 @@ files:
93
107
  - ".travis.yml"
94
108
  - CODE_OF_CONDUCT.md
95
109
  - Gemfile
110
+ - Guardfile
96
111
  - LICENSE.txt
97
112
  - README.md
98
113
  - Rakefile
@@ -138,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
153
  - !ruby/object:Gem::Version
139
154
  version: '0'
140
155
  requirements: []
141
- rubygems_version: 3.2.32
156
+ rubygems_version: 3.3.26
142
157
  signing_key:
143
158
  specification_version: 4
144
159
  summary: Adapter for pseudo-relational data stored in Google Sheets