csv_search 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4aa1a5b35834ede115884f90d9fc26f33a82fb923db0e1372ce3f1a420ae1349
4
+ data.tar.gz: 12954189399ee791dd2cf08691a3c1248af88b4b5cb91b769db3c113542e7e86
5
+ SHA512:
6
+ metadata.gz: c7c0e18e36d719a669464f175ae1f970fdaf0bf3d18f28f07da33b2074adf17573de5c9fe5d48179d6cfe47f9f9b984dc4a0516f759d1f79e5959c3127392499
7
+ data.tar.gz: 86ecb12333ccaf679774351d27fa05e5272586ad1db3a538891ad1c1f8a8fb7cfa3169db8769bd250f638786697d35fef8e9e85691be40170ae5267f70907024
@@ -0,0 +1,11 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'csv_search'
3
+ s.version = '0.0.1'
4
+ s.summary = 'CSV search'
5
+ s.description = 'A simple CSV search'
6
+ s.authors = ['Shang']
7
+ s.email = 'shangweilin7@gmail.com'
8
+ s.files = `git ls-files`.split($/)
9
+ s.homepage = 'https://rubygems.org/gems/csv_search'
10
+ s.license = 'MIT'
11
+ end
@@ -0,0 +1,13 @@
1
+ module CSVRecord
2
+ module Algebra
3
+ class Between
4
+ attr_reader :prok
5
+
6
+ def initialize(args = {})
7
+ minimum = args[:minimum] || 0
8
+ maximum = args[:maximum] || BigDecimal::INFINITY
9
+ @prok = proc { |object| object >= minimum && object <= maximum }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module CSVRecord
2
+ module Delegation
3
+ def self.included(base)
4
+ base.include ClassSpecificRelation
5
+ end
6
+
7
+ module ClassSpecificRelation
8
+ def delegate_to_scoped_klass(method)
9
+ instance_eval(@klass.public_method(method).source)
10
+ end
11
+
12
+ protected
13
+
14
+ def method_missing(method, *args, &block)
15
+ if @klass.respond_to?(method)
16
+ delegate_to_scoped_klass(method)
17
+ public_send(method, *args, &block)
18
+ else
19
+ super
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,98 @@
1
+ require 'csv_search/delegation'
2
+ require 'csv_search/algebra/between'
3
+
4
+ module CSVRecord
5
+ class Relation
6
+ include Delegation
7
+
8
+ attr_reader :klass, :scope, :class_name
9
+
10
+ def initialize(klass)
11
+ @klass = klass
12
+ @class_name = klass.name
13
+ @scope = klass.data.map do |object|
14
+ klass.new(object)
15
+ end
16
+ end
17
+
18
+ def all
19
+ self
20
+ end
21
+
22
+ def where(opts)
23
+ scope.select! do |object|
24
+ object if queries(opts) { |key, query| query.call(object.send(key)) }
25
+ end
26
+ self
27
+ end
28
+
29
+ def find_by(opts)
30
+ scope.find do |object|
31
+ object.values_at(*opts.keys) == opts.values
32
+ end
33
+ end
34
+
35
+ def pluck(*columns)
36
+ scope.map do |object|
37
+ object.values_at(*columns).tap do |datas|
38
+ break datas.first if columns.size == 1
39
+ end
40
+ end
41
+ end
42
+
43
+ def order(*columns)
44
+ scope.sort_by! do |object|
45
+ if columns.first.is_a?(Hash)
46
+ columns.first.map do |column, dir|
47
+ dir.to_sym == :desc ? -object.send(column) : object.send(column)
48
+ end
49
+ else
50
+ columns.map { |column| object.send(column) }
51
+ end
52
+ end
53
+ self
54
+ end
55
+
56
+ def group_by(&block)
57
+ scope.group_by(&block)
58
+ end
59
+
60
+ def each(&block)
61
+ scope.each(&block)
62
+ end
63
+
64
+ def each_with_index(&block)
65
+ scope.each_with_index(&block)
66
+ end
67
+
68
+ def map(&block)
69
+ scope.map(&block)
70
+ end
71
+
72
+ def present?
73
+ scope.present?
74
+ end
75
+
76
+ def to_a
77
+ scope
78
+ end
79
+
80
+ private
81
+
82
+ def queries(opts)
83
+ opts.all? do |key, value|
84
+ next yield key, proc { |object| value == object } unless value.is_a?(Hash)
85
+
86
+ value.all? do |vk, vv|
87
+ case vk
88
+ # where(a: {
89
+ # between: [a, b]
90
+ # })
91
+ when :between
92
+ yield key, Algebra::Between.new(minimum: vv.minimum, maximum: vv.maximum).prok
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
data/lib/csv_search.rb ADDED
@@ -0,0 +1,64 @@
1
+ require 'csv'
2
+ require 'csv_search/relation'
3
+
4
+ module CSVSearch
5
+ class Base
6
+ class << self
7
+ attr_reader :data
8
+
9
+ @data = []
10
+
11
+ def source(file_path)
12
+ @data = CSV.foreach(file_path, headers: true).map(&:to_h)
13
+ end
14
+
15
+ def column_names
16
+ @column_names ||= @data.first.keys.map(&:to_sym)
17
+ end
18
+
19
+ def all
20
+ Relation.new(self).all
21
+ end
22
+
23
+ def where(opts)
24
+ Relation.new(self).where(opts)
25
+ end
26
+
27
+ def find_by(opts)
28
+ Relation.new(self).find_by(opts)
29
+ end
30
+
31
+ def order(*columns)
32
+ Relation.new(self).order(*columns)
33
+ end
34
+
35
+ def pluck(*columns)
36
+ Relation.new(self).pluck(*columns)
37
+ end
38
+ end
39
+
40
+ def initialize(object)
41
+ object.each_pair do |key, value|
42
+ next if self.class.column_names.exclude?(key.to_sym)
43
+
44
+ define_singleton_method(key) do
45
+ instance_variable_get("@#{key}") || instance_variable_set("@#{key}", value)
46
+ end
47
+ end
48
+ end
49
+
50
+ def attributes
51
+ Hash[self.class.column_names.map { |column| [column, send(column)] }]
52
+ end
53
+
54
+ def values_at(*columns)
55
+ columns.map { |column| send(column) }
56
+ end
57
+
58
+ def ==(other)
59
+ return false unless other.is_a?(self.class)
60
+
61
+ values_at(*self.class.column_names) == other.values_at(*self.class.column_names)
62
+ end
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv_search
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Shang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple CSV search
14
+ email: shangweilin7@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - csv_search.gemspec
20
+ - lib/csv_search.rb
21
+ - lib/csv_search/algebra/between.rb
22
+ - lib/csv_search/delegation.rb
23
+ - lib/csv_search/relation.rb
24
+ homepage: https://rubygems.org/gems/csv_search
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubygems_version: 3.1.6
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: CSV search
47
+ test_files: []