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 +7 -0
- data/csv_search.gemspec +11 -0
- data/lib/csv_search/algebra/between.rb +13 -0
- data/lib/csv_search/delegation.rb +24 -0
- data/lib/csv_search/relation.rb +98 -0
- data/lib/csv_search.rb +64 -0
- metadata +47 -0
    
        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
         | 
    
        data/csv_search.gemspec
    ADDED
    
    | @@ -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: []
         |