Skip to content

Commit

Permalink
Extract csv file handling to CSV::Storage
Browse files Browse the repository at this point in the history
Adds `CSV::Storage` to perform the reading and writing to csv files. The
new class is used in the `Dataset` and the `Gateway`. The connection is
passed in to the dataset to keep the command functionality working.
  • Loading branch information
elskwid committed Mar 6, 2017
1 parent 1ce8948 commit c95b75b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 27 deletions.
33 changes: 14 additions & 19 deletions lib/rom/csv/dataset.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
require 'rom/memory/dataset'
require 'rom/csv/storage'

module ROM
module CSV
# Type definition used to constrain the `connection` option
StorageType = Types.Definition(Storage).constrained(type: Storage)

# Dataset for CSV
#
# @api public
class Dataset < ROM::Memory::Dataset
option :path,

# Connection to the file
#
# @return [Storage]
#
# @api private
option :connection,
optional: true,
type: Types::Strict::String
option :file_options,
default: proc { {} },
type: Types::Strict::Hash
type: StorageType

# Convert each CSV::Row to a hash
#
Expand All @@ -21,23 +28,11 @@ def self.row_proc
end

def reload!
@data = load_data
@data = connection.load
end

def sync!
write_data && reload!
end

def write_data
::CSV.open(path, 'wb', file_options) do |csv|
data.to_a.each do |tuple|
csv << tuple
end
end
end

def load_data
::CSV.table(path, file_options).by_row!
connection.dump(data) && reload!
end

def count
Expand Down
11 changes: 3 additions & 8 deletions lib/rom/csv/gateway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'rom/initializer'
require 'rom/csv/dataset'
require 'rom/csv/commands'
require 'rom/csv/storage'

# Ruby Object Mapper
#
Expand Down Expand Up @@ -72,7 +73,7 @@ class Gateway < ROM::Gateway
def initialize(*)
super
@datasets = {}
@connection = ::CSV.table(path, csv_options).by_row!
@connection = Storage.new(path, csv_options)
end

# Return dataset with the given name
Expand All @@ -94,7 +95,7 @@ def [](name)
#
# @api public
def dataset(name)
datasets[name] = Dataset.new(connection, dataset_options)
datasets[name] = Dataset.new(connection.load, connection: connection)
end

# Check if dataset exists
Expand All @@ -105,12 +106,6 @@ def dataset(name)
def dataset?(name)
datasets.key?(name)
end

private

def dataset_options
{ path: path, file_options: csv_options }
end
end
end
end
52 changes: 52 additions & 0 deletions lib/rom/csv/storage.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'csv'
require 'rom/initializer'

module ROM
module CSV
# CSV file storage for datasets
#
# @api private
class Storage
extend Initializer

# Path to the file
#
# @return [String]
#
# @api private
param :path,
type: Types::Strict::String

# Options for file passed to `CSV`
#
# @return [Hash]
#
# @api private
param :csv_options,
default: proc { {} },
type: Types::Strict::Hash

# Dump the data to the file at `path`
#
# @return [undefined]
#
# @api public
def dump(data)
::CSV.open(path, 'wb', csv_options) do |csv|
data.to_a.each do |tuple|
csv << tuple
end
end
end

# Load the data from the file at `path`
#
# @return [CSV::Table]
#
# @api public
def load
::CSV.table(path, csv_options).by_row!
end
end
end
end
4 changes: 4 additions & 0 deletions lib/rom/csv/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ module ROM
module CSV
module Types
include ROM::Types

def self.Definition(primitive)
Dry::Types::Definition.new(primitive)
end
end
end
end

0 comments on commit c95b75b

Please sign in to comment.