csv_search 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []