Class: SheetsDB::Worksheet
- Inherits:
-
Object
- Object
- SheetsDB::Worksheet
show all
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/sheets_db/worksheet.rb,
lib/sheets_db/worksheet/row.rb,
lib/sheets_db/worksheet/column.rb
Defined Under Namespace
Classes: Column, ColumnNotFoundError, Row, WorksheetContainsDataError
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#==(other) ⇒ Object
(also: #eql?)
-
#all ⇒ Object
-
#attribute_at_row_position(attribute_name, row_position) ⇒ Object
-
#attribute_definitions ⇒ Object
-
#clear_google_drive_resource(save: false) ⇒ Object
-
#clear_google_drive_resource! ⇒ Object
-
#column_names ⇒ Object
-
#columns ⇒ Object
-
#convert_to_boolean(raw_value) ⇒ Object
-
#convert_value(raw_value, attribute_definition) ⇒ Object
-
#create!(**attributes) ⇒ Object
-
#delete_google_drive_resource!(force: false) ⇒ Object
-
#disable_synchronization! ⇒ Object
-
#each ⇒ Object
-
#enable_synchronization! ⇒ Object
-
#existing_raw_data ⇒ Object
-
#find_by_attribute(attribute_name, value) ⇒ Object
-
#find_by_id(id) ⇒ Object
-
#find_by_ids(ids) ⇒ Object
-
#first_existing_column_name(attribute_name) ⇒ Object
-
#get_definition_and_column(attribute_name) ⇒ Object
-
#hash ⇒ Object
-
#import!(attribute_sets) ⇒ Object
-
#initialize(spreadsheet:, google_drive_resource:, type: nil) ⇒ Worksheet
constructor
A new instance of Worksheet.
-
#new(**attributes) ⇒ Object
-
#next_available_row_position ⇒ Object
-
#read_value_from_google_drive_resource(dimensions:, attribute_definition:) ⇒ Object
-
#reload! ⇒ Object
-
#set_up! ⇒ Object
-
#synchronize! ⇒ Object
-
#transaction ⇒ Object
-
#truncate! ⇒ Object
-
#type ⇒ Object
-
#update_attribute_at_row_position(attribute_name:, value:, row_position:) ⇒ Object
-
#update_attributes_at_row_position(staged_attributes, row_position:) ⇒ Object
-
#value_if_column_missing(attribute_definition) ⇒ Object
-
#write_matrix(matrix, rewrite: false, save: false) ⇒ Object
-
#write_matrix!(matrix, **options) ⇒ Object
-
#write_raw_data(data, **options) ⇒ Object
-
#write_raw_data!(data, **options) ⇒ Object
Constructor Details
#initialize(spreadsheet:, google_drive_resource:, type: nil) ⇒ Worksheet
Returns a new instance of Worksheet.
17
18
19
20
21
22
|
# File 'lib/sheets_db/worksheet.rb', line 17
def initialize(spreadsheet:, google_drive_resource:, type: nil)
@spreadsheet = spreadsheet
@google_drive_resource = google_drive_resource
@type = type
@synchronizing = true
end
|
Instance Attribute Details
#google_drive_resource ⇒ Object
Returns the value of attribute google_drive_resource.
13
14
15
|
# File 'lib/sheets_db/worksheet.rb', line 13
def google_drive_resource
@google_drive_resource
end
|
#spreadsheet ⇒ Object
Returns the value of attribute spreadsheet.
13
14
15
|
# File 'lib/sheets_db/worksheet.rb', line 13
def spreadsheet
@spreadsheet
end
|
#synchronizing ⇒ Object
Returns the value of attribute synchronizing.
13
14
15
|
# File 'lib/sheets_db/worksheet.rb', line 13
def synchronizing
@synchronizing
end
|
Instance Method Details
#==(other) ⇒ Object
Also known as:
eql?
42
43
44
45
46
|
# File 'lib/sheets_db/worksheet.rb', line 42
def ==(other)
other.is_a?(self.class) &&
other.google_drive_resource == google_drive_resource &&
other.type == type
end
|
#all ⇒ Object
170
171
172
|
# File 'lib/sheets_db/worksheet.rb', line 170
def all
to_a
end
|
#attribute_at_row_position(attribute_name, row_position) ⇒ Object
100
101
102
103
104
105
106
107
|
# File 'lib/sheets_db/worksheet.rb', line 100
def attribute_at_row_position(attribute_name, row_position)
attribute_definition, column = get_definition_and_column(attribute_name)
return value_if_column_missing(attribute_definition) unless column
raw_value = read_value_from_google_drive_resource(
dimensions: [row_position, column.column_position],
attribute_definition: attribute_definition
)
end
|
#attribute_definitions ⇒ Object
71
72
73
|
# File 'lib/sheets_db/worksheet.rb', line 71
def attribute_definitions
type.attribute_definitions
end
|
#clear_google_drive_resource(save: false) ⇒ Object
284
285
286
287
|
# File 'lib/sheets_db/worksheet.rb', line 284
def clear_google_drive_resource(save: false)
empty_matrix = Array.new(google_drive_resource.num_rows, Array.new(google_drive_resource.num_cols))
write_matrix(empty_matrix, save: save)
end
|
#clear_google_drive_resource! ⇒ Object
289
290
291
|
# File 'lib/sheets_db/worksheet.rb', line 289
def clear_google_drive_resource!
clear_google_drive_resource(save: true)
end
|
#column_names ⇒ Object
67
68
69
|
# File 'lib/sheets_db/worksheet.rb', line 67
def column_names
columns.keys
end
|
#columns ⇒ Object
54
55
56
57
58
59
60
61
62
63
64
65
|
# File 'lib/sheets_db/worksheet.rb', line 54
def columns
@columns ||= begin
{}.tap { |directory|
= google_drive_resource.rows.first || []
.each_with_index do |name, i|
unless name == ""
directory[name] = Column.new(name: name, column_position: i + 1)
end
end
}
end
end
|
#convert_to_boolean(raw_value) ⇒ Object
205
206
207
208
209
210
211
|
# File 'lib/sheets_db/worksheet.rb', line 205
def convert_to_boolean(raw_value)
return nil if raw_value.nil?
trues = ["y", "yes", "true", "1"]
falses = ["n", "no", "false", "0"]
return true if trues.include?(raw_value.downcase)
return false if falses.include?(raw_value.downcase)
end
|
#convert_value(raw_value, attribute_definition) ⇒ Object
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'lib/sheets_db/worksheet.rb', line 213
def convert_value(raw_value, attribute_definition)
raw_value = raw_value.strip if attribute_definition.fetch(:strip, true)
return nil if raw_value == ""
converted_value = case attribute_definition[:type].to_s
when "Integer"
raw_value.to_i
when "Decimal"
raw_value.to_d
when "DateTime"
DateTime.strptime(raw_value, "%m/%d/%Y %H:%M:%S")
when "Boolean"
convert_to_boolean(raw_value)
else
raw_value
end
attribute_definition[:transform] ?
attribute_definition[:transform].call(converted_value) :
converted_value
end
|
#create!(**attributes) ⇒ Object
151
152
153
|
# File 'lib/sheets_db/worksheet.rb', line 151
def create!(**attributes)
new(**attributes).save!
end
|
#delete_google_drive_resource!(force: false) ⇒ Object
249
250
251
252
253
254
255
|
# File 'lib/sheets_db/worksheet.rb', line 249
def delete_google_drive_resource!(force: false)
raise WorksheetContainsDataError if google_drive_resource.num_rows.nonzero? && !force
google_drive_resource.delete
@google_drive_resource = nil
spreadsheet.reload!
end
|
#disable_synchronization! ⇒ Object
237
238
239
|
# File 'lib/sheets_db/worksheet.rb', line 237
def disable_synchronization!
@synchronizing = false
end
|
#each ⇒ Object
163
164
165
166
167
168
|
# File 'lib/sheets_db/worksheet.rb', line 163
def each
return to_enum(:each) unless block_given?
(google_drive_resource.num_rows - 1).times do |i|
yield type.new(worksheet: self, row_position: i + 2)
end
end
|
#enable_synchronization! ⇒ Object
233
234
235
|
# File 'lib/sheets_db/worksheet.rb', line 233
def enable_synchronization!
@synchronizing = true
end
|
#existing_raw_data ⇒ Object
299
300
301
302
303
304
|
# File 'lib/sheets_db/worksheet.rb', line 299
def existing_raw_data
@existing_raw_data ||= begin
rows = google_drive_resource.rows
rows.drop(1).map { |row| Hash[rows.first.zip(row)] }
end
end
|
#find_by_attribute(attribute_name, value) ⇒ Object
189
190
191
192
193
194
195
|
# File 'lib/sheets_db/worksheet.rb', line 189
def find_by_attribute(attribute_name, value)
definition = attribute_definitions[attribute_name]
select { |item|
attribute = item.send(attribute_name)
definition[:multiple] ? attribute.include?(value) : attribute == value
}
end
|
#find_by_id(id) ⇒ Object
174
175
176
|
# File 'lib/sheets_db/worksheet.rb', line 174
def find_by_id(id)
find_by_ids([id]).first
end
|
#find_by_ids(ids) ⇒ Object
178
179
180
181
182
183
184
185
186
187
|
# File 'lib/sheets_db/worksheet.rb', line 178
def find_by_ids(ids)
result = []
each do |model|
break if result.count == ids.count
if ids.include?(model.id)
result << model
end
end
result
end
|
#first_existing_column_name(attribute_name) ⇒ Object
83
84
85
86
87
88
89
90
91
|
# File 'lib/sheets_db/worksheet.rb', line 83
def first_existing_column_name(attribute_name)
attribute_definition = attribute_definitions.fetch(attribute_name)
[
attribute_definition.fetch(:column_name, attribute_name),
attribute_definition.fetch(:aliases, [])
].flatten.detect { |name|
columns.key?(name.to_s)
}
end
|
#get_definition_and_column(attribute_name) ⇒ Object
75
76
77
78
79
80
81
|
# File 'lib/sheets_db/worksheet.rb', line 75
def get_definition_and_column(attribute_name)
column_name = first_existing_column_name(attribute_name)
[
attribute_definitions.fetch(attribute_name),
column_name && columns[column_name.to_s]
]
end
|
#hash ⇒ Object
50
51
52
|
# File 'lib/sheets_db/worksheet.rb', line 50
def hash
[self.class, google_drive_resource, type].hash
end
|
#import!(attribute_sets) ⇒ Object
155
156
157
158
159
160
161
|
# File 'lib/sheets_db/worksheet.rb', line 155
def import!(attribute_sets)
transaction do
attribute_sets.each do |attributes|
create!(**attributes)
end
end
end
|
#new(**attributes) ⇒ Object
145
146
147
148
149
|
# File 'lib/sheets_db/worksheet.rb', line 145
def new(**attributes)
type.new(worksheet: self, row_position: nil).tap { |row|
row.stage_attributes(attributes)
}
end
|
#next_available_row_position ⇒ Object
141
142
143
|
# File 'lib/sheets_db/worksheet.rb', line 141
def next_available_row_position
google_drive_resource.num_rows + 1
end
|
#read_value_from_google_drive_resource(dimensions:, attribute_definition:) ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/sheets_db/worksheet.rb', line 109
def read_value_from_google_drive_resource(dimensions:, attribute_definition:)
raw_value = case attribute_definition[:type].to_s
when "DateTime"
google_drive_resource.input_value(*dimensions)
else
google_drive_resource[*dimensions]
end
if attribute_definition[:multiple]
raw_value.split(/,\s*/).map { |value| convert_value(value, attribute_definition) }
else
convert_value(raw_value, attribute_definition)
end
end
|
#reload! ⇒ Object
197
198
199
200
201
202
203
|
# File 'lib/sheets_db/worksheet.rb', line 197
def reload!
@columns = nil
@existing_raw_data = nil
@generated_type = nil
google_drive_resource.reload
self
end
|
#set_up! ⇒ Object
24
25
26
27
28
29
30
|
# File 'lib/sheets_db/worksheet.rb', line 24
def set_up!
if google_drive_resource.num_rows == 0
registered_column_names = attribute_definitions.map { |name, definition| definition[:column_name] }
write_matrix!([registered_column_names])
end
self
end
|
#synchronize! ⇒ Object
293
294
295
296
297
|
# File 'lib/sheets_db/worksheet.rb', line 293
def synchronize!
google_drive_resource.synchronize
@existing_raw_data = nil
self
end
|
#transaction ⇒ Object
241
242
243
244
245
246
247
|
# File 'lib/sheets_db/worksheet.rb', line 241
def transaction
disable_synchronization!
yield
synchronize!
ensure
enable_synchronization!
end
|
#truncate! ⇒ Object
257
258
259
260
261
|
# File 'lib/sheets_db/worksheet.rb', line 257
def truncate!
clear_google_drive_resource!
set_up!
reload!
end
|
#type ⇒ Object
32
33
34
35
36
37
38
39
40
|
# File 'lib/sheets_db/worksheet.rb', line 32
def type
@type || @generated_type ||= begin
Class.new(Row).tap { |generated_type_class|
column_names.each do |name|
generated_type_class.attribute name.to_sym
end
}
end
end
|
#update_attribute_at_row_position(attribute_name:, value:, row_position:) ⇒ Object
134
135
136
137
138
139
|
# File 'lib/sheets_db/worksheet.rb', line 134
def update_attribute_at_row_position(attribute_name:, value:, row_position:)
attribute_definition, column = get_definition_and_column(attribute_name)
raise ColumnNotFoundError, column unless column
assignment_value = attribute_definition[:multiple] ? value.join(",") : value
google_drive_resource[row_position, column.column_position] = assignment_value
end
|
#update_attributes_at_row_position(staged_attributes, row_position:) ⇒ Object
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/sheets_db/worksheet.rb', line 123
def update_attributes_at_row_position(staged_attributes, row_position:)
staged_attributes.each do |attribute_name, value|
update_attribute_at_row_position(
attribute_name: attribute_name,
value: value,
row_position: row_position
)
end
synchronize! if synchronizing
end
|
#value_if_column_missing(attribute_definition) ⇒ Object
93
94
95
96
97
98
|
# File 'lib/sheets_db/worksheet.rb', line 93
def value_if_column_missing(attribute_definition)
unless attribute_definition[:if_column_missing]
raise ColumnNotFoundError, attribute_definition[:column_name]
end
instance_exec(&attribute_definition[:if_column_missing])
end
|
#write_matrix(matrix, rewrite: false, save: false) ⇒ Object
263
264
265
266
267
268
|
# File 'lib/sheets_db/worksheet.rb', line 263
def write_matrix(matrix, rewrite: false, save: false)
clear_google_drive_resource if rewrite
google_drive_resource.update_cells(1, 1, matrix)
synchronize! if save
self
end
|
#write_matrix!(matrix, **options) ⇒ Object
270
271
272
|
# File 'lib/sheets_db/worksheet.rb', line 270
def write_matrix!(matrix, **options)
write_matrix(matrix, **options.merge(save: true))
end
|
#write_raw_data(data, **options) ⇒ Object
274
275
276
277
278
|
# File 'lib/sheets_db/worksheet.rb', line 274
def write_raw_data(data, **options)
raise ArgumentError, "mismatched keys" if data.map(&:keys).uniq.count > 1
write_matrix(data.map(&:values).prepend(data.first.keys), **options)
end
|
#write_raw_data!(data, **options) ⇒ Object
280
281
282
|
# File 'lib/sheets_db/worksheet.rb', line 280
def write_raw_data!(data, **options)
write_raw_data(data, **options.merge(save: true))
end
|