Class: SheetsDB::Worksheet

Inherits:
Object
  • Object
show all
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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spreadsheet:, google_drive_resource:, type:) ⇒ Worksheet

Returns a new instance of Worksheet.



12
13
14
15
16
17
# File 'lib/sheets_db/worksheet.rb', line 12

def initialize(spreadsheet:, google_drive_resource:, type:)
  @spreadsheet = spreadsheet
  @google_drive_resource = google_drive_resource
  @type = type
  @synchronizing = true
end

Instance Attribute Details

#google_drive_resourceObject (readonly)

Returns the value of attribute google_drive_resource.



10
11
12
# File 'lib/sheets_db/worksheet.rb', line 10

def google_drive_resource
  @google_drive_resource
end

#spreadsheetObject (readonly)

Returns the value of attribute spreadsheet.



10
11
12
# File 'lib/sheets_db/worksheet.rb', line 10

def spreadsheet
  @spreadsheet
end

#synchronizingObject (readonly)

Returns the value of attribute synchronizing.



10
11
12
# File 'lib/sheets_db/worksheet.rb', line 10

def synchronizing
  @synchronizing
end

#typeObject (readonly)

Returns the value of attribute type.



10
11
12
# File 'lib/sheets_db/worksheet.rb', line 10

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



19
20
21
22
23
# File 'lib/sheets_db/worksheet.rb', line 19

def ==(other)
  other.is_a?(self.class) &&
    other.google_drive_resource == google_drive_resource &&
    other.type == type
end

#allObject



129
130
131
# File 'lib/sheets_db/worksheet.rb', line 129

def all
  to_a
end

#attribute_at_row_position(attribute_name, row_position) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/sheets_db/worksheet.rb', line 67

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_definitionsObject



47
48
49
# File 'lib/sheets_db/worksheet.rb', line 47

def attribute_definitions
  type.attribute_definitions
end

#column_namesObject



43
44
45
# File 'lib/sheets_db/worksheet.rb', line 43

def column_names
  columns.keys
end

#columnsObject



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/sheets_db/worksheet.rb', line 31

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



160
161
162
163
164
165
166
# File 'lib/sheets_db/worksheet.rb', line 160

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



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/sheets_db/worksheet.rb', line 168

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 "Float"
    raw_value.to_f
  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



110
111
112
# File 'lib/sheets_db/worksheet.rb', line 110

def create!(**attributes)
  new(**attributes).save!
end

#disable_synchronization!Object



192
193
194
# File 'lib/sheets_db/worksheet.rb', line 192

def disable_synchronization!
  @synchronizing = false
end

#eachObject



122
123
124
125
126
127
# File 'lib/sheets_db/worksheet.rb', line 122

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



188
189
190
# File 'lib/sheets_db/worksheet.rb', line 188

def enable_synchronization!
  @synchronizing = true
end

#find_by_attribute(attribute_name, value) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/sheets_db/worksheet.rb', line 148

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



133
134
135
# File 'lib/sheets_db/worksheet.rb', line 133

def find_by_id(id)
  find_by_ids([id]).first
end

#find_by_ids(ids) ⇒ Object



137
138
139
140
141
142
143
144
145
146
# File 'lib/sheets_db/worksheet.rb', line 137

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

#get_definition_and_column(attribute_name) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/sheets_db/worksheet.rb', line 51

def get_definition_and_column(attribute_name)
  attribute_definition = attribute_definitions.fetch(attribute_name)
  column_name = attribute_definition.fetch(:column_name, attribute_name)
  [
    attribute_definition,
    columns[column_name.to_s]
  ]
end

#hashObject



27
28
29
# File 'lib/sheets_db/worksheet.rb', line 27

def hash
  [self.class, google_drive_resource, type].hash
end

#import!(attribute_sets) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/sheets_db/worksheet.rb', line 114

def import!(attribute_sets)
  transaction do
    attribute_sets.each do |attributes|
      create!(**attributes)
    end
  end
end

#new(**attributes) ⇒ Object



104
105
106
107
108
# File 'lib/sheets_db/worksheet.rb', line 104

def new(**attributes)
  type.new(worksheet: self, row_position: nil).tap { |row|
    row.stage_attributes(attributes)
  }
end

#next_available_row_positionObject



100
101
102
# File 'lib/sheets_db/worksheet.rb', line 100

def next_available_row_position
  google_drive_resource.num_rows + 1
end

#read_value_from_google_drive_resource(dimensions:, attribute_definition:) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sheets_db/worksheet.rb', line 76

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



156
157
158
# File 'lib/sheets_db/worksheet.rb', line 156

def reload!
  google_drive_resource.reload
end

#transactionObject



196
197
198
199
200
201
202
# File 'lib/sheets_db/worksheet.rb', line 196

def transaction
  disable_synchronization!
  yield
  google_drive_resource.synchronize
ensure
  enable_synchronization!
end

#update_attributes_at_row_position(staged_attributes, row_position:) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/sheets_db/worksheet.rb', line 90

def update_attributes_at_row_position(staged_attributes, row_position:)
  staged_attributes.each do |attribute_name, value|
    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
  google_drive_resource.synchronize if synchronizing
end

#value_if_column_missing(attribute_definition) ⇒ Object



60
61
62
63
64
65
# File 'lib/sheets_db/worksheet.rb', line 60

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