uber_array 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.rubocop.yml +57 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +2 -0
- data/LICENSE.md +13 -0
- data/README.md +71 -0
- data/Rakefile +8 -0
- data/lib/uber_array.rb +130 -0
- data/lib/uber_array/version.rb +3 -0
- data/spec/fixtures/items.yml +55 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/uber_array_spec.rb +200 -0
- data/uber_array.gemspec +25 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5eaa7aae77cd713169e5148fc0b5d7d4deffe6b1
|
4
|
+
data.tar.gz: 1dcb67cd4983d0fca9186a699feac341419e5d09
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb67ba7fd12560804a0fb645c6ca31ede7127bfbc14e47f6dc0cc7442327579c9c3035019a94924a0f453d693a6f9a63e81b33102a3ec56a32295a67ee9da87d
|
7
|
+
data.tar.gz: aef965890618882796892310279d59bab15774c8dd97a3b66ba1fb4979bc873e975cb9e58f79718a0117a0ec20e160df869c13892a4073550cb3408039bf84d6
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
AllCops:
|
2
|
+
Excludes:
|
3
|
+
- temp/*
|
4
|
+
|
5
|
+
Encoding:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
AmbiguousOperator:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
CaseIndentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
CyclomaticComplexity:
|
15
|
+
Enabled: false
|
16
|
+
Max: 10
|
17
|
+
|
18
|
+
PerceivedComplexity:
|
19
|
+
Enabled: false
|
20
|
+
Max: 10
|
21
|
+
|
22
|
+
Documentation:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
EmptyLinesAroundBody:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
HashSyntax:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
ClassLength:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
LineLength:
|
35
|
+
Enabled: true
|
36
|
+
Max: 160
|
37
|
+
|
38
|
+
MethodLength:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
ModuleFunction:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
NestedTernaryOperator:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
RaiseArgs:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
RescueModifier:
|
51
|
+
Enabled: false
|
52
|
+
|
53
|
+
SymbolProc:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
UnusedMethodArgument:
|
57
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2015, Opower
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#uber_array
|
2
|
+
|
3
|
+
`UberArray` is an `Array` based datatype that enables SQL-like `where` syntax for arrays of Hashes or Objects.
|
4
|
+
|
5
|
+
In Hash based arrays each element is a Hash with symbols or strings as keys.
|
6
|
+
In Object based arrays each element is an Object-derived instance that responds to attribute names instead of keys.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'uber_array'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle install
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install uber_array
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'uber_array'
|
26
|
+
|
27
|
+
# Array of Hash elements with strings as keys
|
28
|
+
items = [
|
29
|
+
{ 'name' => 'Jack', 'score' => 999, 'active' => false },
|
30
|
+
{ 'name' => 'Jake', 'score' => 888, 'active' => true },
|
31
|
+
{ 'name' => 'John', 'score' => 777, 'active' => true }
|
32
|
+
]
|
33
|
+
|
34
|
+
uber_items = UberArray.new(items)
|
35
|
+
|
36
|
+
uber_items.where('name' => 'John')
|
37
|
+
uber_items.where('name' => /Ja/i)
|
38
|
+
uber_items.like('ja')
|
39
|
+
uber_items.where('name' => %w(Dave John Tom))
|
40
|
+
uber_items.where('score' => 999)
|
41
|
+
uber_items.where('score' => ->(s){s > 900})
|
42
|
+
uber_items.where('active' => true, 'score' => 800..900)
|
43
|
+
uber_items.map_by('name')
|
44
|
+
|
45
|
+
Player = Struct.new(:name, :score, :active)
|
46
|
+
|
47
|
+
# Array of Object-like Struct elements with attributes
|
48
|
+
objs = [
|
49
|
+
Player.new('Jack', 999, false),
|
50
|
+
Player.new('Jake', 888, true),
|
51
|
+
Player.new('John', 777, true)
|
52
|
+
]
|
53
|
+
|
54
|
+
uber_objs = UberArray.new(objs, :primary_key => :__name__)
|
55
|
+
|
56
|
+
uber_objs.where(:__name__ => 'John')
|
57
|
+
uber_objs.where(:__name__ => /Ja/i)
|
58
|
+
uber_objs.like('ja')
|
59
|
+
uber_objs.where(:__name__ => %w(Dave John Tom))
|
60
|
+
uber_objs.where(:__score__ => 999)
|
61
|
+
uber_objs.where(:__score__ => ->(s){s > 900})
|
62
|
+
uber_objs.where(:__active__ => true, :__score__ => 800..900)
|
63
|
+
```
|
64
|
+
|
65
|
+
### Contributing
|
66
|
+
|
67
|
+
1. Fork it
|
68
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
69
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
70
|
+
4. Push to the branch (git push origin my-new-feature)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/uber_array.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
class UberArray
|
2
|
+
attr_accessor :array, :primary_key
|
3
|
+
|
4
|
+
# @param array [Array<Hash|Object>] underlying array
|
5
|
+
# @param options [Hash] init options
|
6
|
+
# @option options [String|Symbol] :primary_key Name of primary key or attribute
|
7
|
+
# attribute/method names are specified as symbols like :__name__
|
8
|
+
def initialize(array = [], options = {})
|
9
|
+
@array = array || []
|
10
|
+
@primary_key = options[:primary_key] || 'name'
|
11
|
+
end
|
12
|
+
|
13
|
+
# get current config options
|
14
|
+
def uberopts
|
15
|
+
{ primary_key: primary_key }
|
16
|
+
end
|
17
|
+
|
18
|
+
# delegate all methods to the inner @array,
|
19
|
+
# if the result is an Array with elements of the same type as @array - convert it to UberArray
|
20
|
+
def method_missing(method, *args, &block)
|
21
|
+
klass = @array.first.class
|
22
|
+
result = @array.send(method, *args, &block)
|
23
|
+
if result.is_a?(Array)
|
24
|
+
@array.empty? || result.empty? || result.first.class == klass ? UberArray.new(result, uberopts) : result
|
25
|
+
else
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param key [String|Symbol] key name to map by
|
31
|
+
def map_by(key)
|
32
|
+
@array.map { |i| i[key] }
|
33
|
+
end
|
34
|
+
|
35
|
+
# build a Proc by which to filter items in @array
|
36
|
+
# @params opts [Hash] filter options
|
37
|
+
def filter_proc(opts = {})
|
38
|
+
fail ArgumentError, 'Hash argument expected' unless opts.is_a?(Hash)
|
39
|
+
|
40
|
+
if opts.empty?
|
41
|
+
-> { false }
|
42
|
+
else
|
43
|
+
lambda do |item|
|
44
|
+
opts.map do |key, val|
|
45
|
+
can_respond, ival = item_send_if_respond_to?(item, key)
|
46
|
+
can_respond &&
|
47
|
+
case val
|
48
|
+
# :key => ->(v){v > 12}
|
49
|
+
when Proc
|
50
|
+
val.call(ival)
|
51
|
+
# :key => /text/
|
52
|
+
when Regexp
|
53
|
+
ival =~ val
|
54
|
+
# :key => 1..4, :key => [1,2,3,4]
|
55
|
+
when Array, Range
|
56
|
+
val.to_a.include?(ival)
|
57
|
+
# :key => false|true, :key => 'text', :key => 10
|
58
|
+
else
|
59
|
+
ival == val
|
60
|
+
end
|
61
|
+
end.all?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# check if key represents a method/attribute name and return it if so
|
67
|
+
# @param key [String|Symbol] key name
|
68
|
+
def method_name?(key)
|
69
|
+
key.is_a?(Symbol) && /^__(?<name>.+)__$/ =~ key ? name.to_sym : nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# check if item responds to a given key/attribute name
|
73
|
+
def item_respond_to?(item, key)
|
74
|
+
method = method_name?(key) || :[]
|
75
|
+
item.respond_to?(method)
|
76
|
+
end
|
77
|
+
|
78
|
+
# invoke the given key/attribute name as a method on item
|
79
|
+
def item_send(item, key)
|
80
|
+
method = method_name?(key)
|
81
|
+
method ? item.send(method) : item[key]
|
82
|
+
end
|
83
|
+
|
84
|
+
# send a key/method name to an item if the item responds to it
|
85
|
+
# @param item [Hash|Object] item of @array
|
86
|
+
# @param key [String|Symbol] key name
|
87
|
+
def item_send_if_respond_to?(item, key)
|
88
|
+
can_respond, result = nil, nil
|
89
|
+
method = method_name?(key)
|
90
|
+
if method
|
91
|
+
can_respond = item.respond_to?(method)
|
92
|
+
result = item.send(method) if can_respond
|
93
|
+
else
|
94
|
+
can_respond = item.respond_to?(:[])
|
95
|
+
result = item[key] if can_respond
|
96
|
+
end
|
97
|
+
[can_respond, result]
|
98
|
+
end
|
99
|
+
|
100
|
+
# filter items in @array
|
101
|
+
# @params opts [Hash] filter options
|
102
|
+
# Keys are key names (e.g. :name, 'name') for Hash-based elements
|
103
|
+
# or attribute names (e.g. :__name__) for Object-based elements
|
104
|
+
def where(opts = {})
|
105
|
+
return UberArray.new([], uberopts) if opts.empty?
|
106
|
+
result = @array.select(&filter_proc(opts))
|
107
|
+
UberArray.new(result, uberopts)
|
108
|
+
end
|
109
|
+
alias_method :filter, :where
|
110
|
+
|
111
|
+
# filter items by regex matching on @primary_key
|
112
|
+
def like(regex)
|
113
|
+
exp = regex.is_a?(String) ? Regexp.new(regex, true) : regex
|
114
|
+
where(primary_key => exp)
|
115
|
+
end
|
116
|
+
|
117
|
+
# use a non-number as access key into @array
|
118
|
+
# with elements responding to a key or attribute name specified by @primary_key
|
119
|
+
def [](key)
|
120
|
+
return @array[key] if key.is_a?(Fixnum)
|
121
|
+
method = method_name?(primary_key)
|
122
|
+
@array.find do |item|
|
123
|
+
if method
|
124
|
+
item.respond_to?(method) && item.send(method) == key
|
125
|
+
else
|
126
|
+
item.respond_to?(:[]) && item[primary_key] == key
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
- id: 0a
|
3
|
+
name: John Doe
|
4
|
+
team: ninjas
|
5
|
+
score: 800
|
6
|
+
email: john.doe@test.com
|
7
|
+
phone:
|
8
|
+
voice: 1234
|
9
|
+
sms: 6789
|
10
|
+
admin: false
|
11
|
+
active: true
|
12
|
+
|
13
|
+
- id: 1b
|
14
|
+
name: Jim Black
|
15
|
+
team: punks
|
16
|
+
score: 900
|
17
|
+
email: jim.black@ping.me
|
18
|
+
phone:
|
19
|
+
voice: 2345
|
20
|
+
sms: 5678
|
21
|
+
admin: false
|
22
|
+
active: false
|
23
|
+
|
24
|
+
- id: 2c
|
25
|
+
name: Anne Kim
|
26
|
+
team: sisters
|
27
|
+
score: 678
|
28
|
+
email: anne@sista.net
|
29
|
+
phone:
|
30
|
+
voice:
|
31
|
+
sms:
|
32
|
+
admin: false
|
33
|
+
active: true
|
34
|
+
|
35
|
+
- id: 3d
|
36
|
+
name: Sandi
|
37
|
+
team: sisters
|
38
|
+
score: 555
|
39
|
+
email: sandi@sista.net
|
40
|
+
phone:
|
41
|
+
voice: 2222
|
42
|
+
sms:
|
43
|
+
admin: false
|
44
|
+
active: false
|
45
|
+
|
46
|
+
- id: 4e
|
47
|
+
name: Zak
|
48
|
+
team: ninjas
|
49
|
+
score: 999
|
50
|
+
email: captain@test.me
|
51
|
+
phone:
|
52
|
+
voice: 7777
|
53
|
+
sms:
|
54
|
+
admin: true
|
55
|
+
active: true
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'yaml'
|
3
|
+
require 'uber_array'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.expect_with :rspec do |c|
|
7
|
+
c.syntax = :expect
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_fixtures
|
11
|
+
file = '../fixtures/items.yml'
|
12
|
+
YAML.load_file(File.expand_path(file, __FILE__))
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
module UberArraySpec
|
2
|
+
|
3
|
+
class Item
|
4
|
+
def initialize(options = {})
|
5
|
+
options.each do |key, val|
|
6
|
+
instance_variable_set("@#{key}", val)
|
7
|
+
self.class.send(:attr_reader, key.to_sym)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe UberArray do
|
13
|
+
# each array element is a Hash with string key names
|
14
|
+
let(:items_str) { load_fixtures }
|
15
|
+
# each array element is a Hash with symbolized key names
|
16
|
+
let(:items_sym) { items_str.map { |i| Hash[i.map { |(k, v)| [k.to_sym, v] }] } }
|
17
|
+
# each array element is an Item object with attributes instead of key names
|
18
|
+
let(:items_obj) { items_str.map { |i| Item.new(i) } }
|
19
|
+
|
20
|
+
# UberArray instances
|
21
|
+
subject(:array_sym) { UberArray.new(items_sym) }
|
22
|
+
subject(:array_str) { UberArray.new(items_str) }
|
23
|
+
subject(:array_obj) { UberArray.new(items_obj) }
|
24
|
+
|
25
|
+
let(:names) { items_sym.map { |i| i[:name] } }
|
26
|
+
let(:name) { 'Sandi' }
|
27
|
+
|
28
|
+
it 'delegates to the inner Array' do
|
29
|
+
expect(array_sym.respond_to?(:size)).to be false
|
30
|
+
expect(array_sym.size).to eq(5)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns an UberArray when resulting elements are of the same type' do
|
34
|
+
expect(array_str.reverse).to be_a UberArray
|
35
|
+
expect(array_sym.sample(2)).to be_a UberArray
|
36
|
+
expect(array_sym.select { |i| i[:active] }).to be_a UberArray
|
37
|
+
expect(array_obj.select { |i| i.active }).to be_a UberArray
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns a regular Array when resulting elements are of a different type' do
|
41
|
+
expect(array_str.map { |i| Item.new(i) }).not_to be_a UberArray
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#method_name?' do
|
45
|
+
it 'extracts method name' do
|
46
|
+
[
|
47
|
+
# input_key => result
|
48
|
+
[:__name__, :name],
|
49
|
+
[:___name___, :_name_],
|
50
|
+
[:_name_, nil],
|
51
|
+
['__name__', nil]
|
52
|
+
].each { |key, rez| expect(array_sym.method_name?(key)).to eq rez }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#map_by' do
|
57
|
+
it 'maps by string' do
|
58
|
+
expect(array_str.map_by('name')).to eq names
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'maps by symbol' do
|
62
|
+
expect(array_sym.map_by(:name)).to eq names
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'maps by attribute name' do
|
66
|
+
expect(array_obj.map(&:name)).to eq names
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#where' do
|
71
|
+
it 'filters by {string => String}' do
|
72
|
+
# where item['name'] equals name
|
73
|
+
expect(array_str.where('name' => name).array).to eq items_str.values_at(3)
|
74
|
+
expect(array_sym.where('name' => name).array).to be_empty
|
75
|
+
expect(array_obj.where('name' => name).array).to be_empty
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'filters by {:symbol => String}' do
|
79
|
+
# where item['name'] equals name
|
80
|
+
expect(array_str.where(:name => name).array).to be_empty
|
81
|
+
expect(array_sym.where(:name => name).array).to eq items_sym.values_at(3)
|
82
|
+
expect(array_obj.where(:name => name).array).to be_empty
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'filters by {:__symbol__ => String}' do
|
86
|
+
# where item.name equals name
|
87
|
+
expect(array_str.where(:__name__ => name).array).to be_empty
|
88
|
+
expect(array_sym.where(:__name__ => name).array).to be_empty
|
89
|
+
expect(array_obj.where(:__name__ => name).array).to eq items_obj.values_at(3)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'filters by {key => Regexp}' do
|
93
|
+
regex = /test/
|
94
|
+
# where item['email'] is like regex
|
95
|
+
expect(array_str.where('email' => regex).array).to eq items_str.values_at(0, 4)
|
96
|
+
expect(array_sym.where(:email => regex).array).to eq items_sym.values_at(0, 4)
|
97
|
+
expect(array_obj.where(:__email__ => regex).array).to eq items_obj.values_at(0, 4)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'filters by {key => Boolean}' do
|
101
|
+
# where item['admin'] is true
|
102
|
+
expect(array_str.where('admin' => true).array).to eq items_str.values_at(4)
|
103
|
+
expect(array_sym.where(:admin => true).array).to eq items_sym.values_at(4)
|
104
|
+
expect(array_obj.where(:__admin__ => true).array).to eq items_obj.values_at(4)
|
105
|
+
# where item['active'] is false
|
106
|
+
expect(array_str.where('active' => false).array).to eq items_str.values_at(1, 3)
|
107
|
+
expect(array_sym.where(:active => false).array).to eq items_sym.values_at(1, 3)
|
108
|
+
expect(array_obj.where(:__active__ => false).array).to eq items_obj.values_at(1, 3)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'filters by {key => Proc}' do
|
112
|
+
prok = ->(score) { score > 900 }
|
113
|
+
# where item['score'] < 900
|
114
|
+
expect(array_str.where('score' => prok).array).to eq items_str.values_at(4)
|
115
|
+
expect(array_sym.where(:score => prok).array).to eq items_sym.values_at(4)
|
116
|
+
expect(array_obj.where(:__score__ => prok).array).to eq items_obj.values_at(4)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'filters by {key => Range}' do
|
120
|
+
range = 500..700
|
121
|
+
# where item['score'] is in range
|
122
|
+
expect(array_str.where('score' => range).array).to eq items_str.values_at(2, 3)
|
123
|
+
expect(array_sym.where(:score => range).array).to eq items_sym.values_at(2, 3)
|
124
|
+
expect(array_obj.where(:__score__ => range).array).to eq items_obj.values_at(2, 3)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'filters by {key => Array}' do
|
128
|
+
teams = %w(bots ninjas)
|
129
|
+
# where item['team'] is a member of teams
|
130
|
+
expect(array_str.where('team' => teams).array).to eq items_str.values_at(0, 4)
|
131
|
+
expect(array_sym.where(:team => teams).array).to eq items_sym.values_at(0, 4)
|
132
|
+
expect(array_obj.where(:__team__ => teams).array).to eq items_obj.values_at(0, 4)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'filters by multiple criteria' do
|
136
|
+
# where item['active'] is true AND item['score'] < 700
|
137
|
+
filter = { 'active' => true, 'score' => ->(s) { s < 700 } }
|
138
|
+
expect(array_str.where(filter).array).to eq items_str.values_at(2)
|
139
|
+
# where item[:team] equals team AND item[:admin] is true
|
140
|
+
filter = { :team => 'ninjas', :admin => true }
|
141
|
+
expect(array_sym.where(filter).array).to eq items_sym.values_at(4)
|
142
|
+
# where item.email is like regex AND item.phone['sms'] is not nil
|
143
|
+
filter = { :__email__ => /test/, :__phone__ => ->p { p['sms'] } }
|
144
|
+
expect(array_obj.where(filter).array).to eq items_obj.values_at(0)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'supports chaining' do
|
148
|
+
team = 'ninjas'
|
149
|
+
expect(array_sym.where(active: true).where(team: team).array).to eq items_sym.values_at(0, 4)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#like' do
|
154
|
+
it 'filters by regex matching on primary_key' do
|
155
|
+
['an', /an/i].each do |regex|
|
156
|
+
# where item['name'] =~ regex
|
157
|
+
expect(array_str.like(regex).array).to eq items_str.values_at(2, 3)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#[]' do
|
163
|
+
it 'references elements by index' do
|
164
|
+
expect(array_str[1]).to eq items_str[1]
|
165
|
+
end
|
166
|
+
|
167
|
+
it "references items by the value of primary_key 'name'" do
|
168
|
+
# primary_key is a string key 'name' by default
|
169
|
+
expect(array_str[name]).to eq array_str[3]
|
170
|
+
expect(array_sym[name]).to eq nil
|
171
|
+
expect(array_obj[name]).to eq nil
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'references items by the value of primary_key :name' do
|
175
|
+
# primary_key is a symbol key :name
|
176
|
+
[array_str, array_sym, array_obj].each { |a| a.primary_key = :name }
|
177
|
+
expect(array_str[name]).to eq nil
|
178
|
+
expect(array_sym[name]).to eq array_sym[3]
|
179
|
+
expect(array_obj[name]).to eq nil
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'references items by the value of primary_key :__name__' do
|
183
|
+
# primary_key is an attribute :__name__
|
184
|
+
[array_str, array_sym, array_obj].each { |a| a.primary_key = :__name__ }
|
185
|
+
expect(array_str[name]).to eq nil
|
186
|
+
expect(array_sym[name]).to eq nil
|
187
|
+
expect(array_obj[name]).to eq array_obj[3]
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'references items by the value of primary_key :id' do
|
191
|
+
id = '3d'
|
192
|
+
# primary_key is a symbol key :id
|
193
|
+
[array_str, array_sym, array_obj].each { |a| a.primary_key = :id }
|
194
|
+
expect(array_str[id]).to eq nil
|
195
|
+
expect(array_sym[id]).to eq array_sym[3]
|
196
|
+
expect(array_obj[id]).to eq nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
data/uber_array.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/uber_array/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'uber_array'
|
6
|
+
spec.version = UberArray::VERSION
|
7
|
+
spec.summary = 'Array based datatype with SQL-like syntax'
|
8
|
+
spec.description = "Enables SQL-like 'where' syntax for arrays of Hashes or Objects"
|
9
|
+
spec.homepage = 'https://github.com/alpinweis/uber_array'
|
10
|
+
|
11
|
+
spec.authors = ['Adrian Kazaku']
|
12
|
+
spec.email = ['alpinweis@gmail.com']
|
13
|
+
|
14
|
+
spec.license = 'Apache-2.0'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
17
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'pry', '~> 0.10'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.1'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
24
|
+
# spec.add_development_dependency 'rubocop', '= 0.26.1'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uber_array
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adrian Kazaku
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
description: Enables SQL-like 'where' syntax for arrays of Hashes or Objects
|
56
|
+
email:
|
57
|
+
- alpinweis@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- ".rubocop.yml"
|
65
|
+
- CHANGELOG.md
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.md
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- lib/uber_array.rb
|
71
|
+
- lib/uber_array/version.rb
|
72
|
+
- spec/fixtures/items.yml
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
- spec/uber_array_spec.rb
|
75
|
+
- uber_array.gemspec
|
76
|
+
homepage: https://github.com/alpinweis/uber_array
|
77
|
+
licenses:
|
78
|
+
- Apache-2.0
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.5.1
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Array based datatype with SQL-like syntax
|
100
|
+
test_files:
|
101
|
+
- spec/fixtures/items.yml
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/uber_array_spec.rb
|