unidata 0.0.5 → 0.0.6
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.
- data/README.md +30 -5
- data/lib/unidata.rb +1 -0
- data/lib/unidata/connection.rb +7 -0
- data/lib/unidata/model.rb +16 -0
- data/lib/unidata/select_list.rb +31 -0
- data/lib/unidata/version.rb +1 -1
- data/spec/spec_helper.rb +10 -0
- data/spec/unidata/connection_spec.rb +27 -0
- data/spec/unidata/model_spec.rb +66 -0
- data/spec/unidata/select_list_spec.rb +35 -0
- metadata +5 -2
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
UniData ORM [](http://travis-ci.org/jisraelsen/unidata)
|
1
|
+
UniData ORM [](http://travis-ci.org/jisraelsen/unidata) [](https://codeclimate.com/github/jisraelsen/unidata)
|
2
2
|
===========
|
3
3
|
|
4
4
|
A simple ORM for Rocket's UniData database.
|
@@ -21,7 +21,32 @@ Or install it yourself as:
|
|
21
21
|
Usage
|
22
22
|
-----
|
23
23
|
|
24
|
-
|
24
|
+
### Connecting to Unidata:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Unidata.prepare_connection(
|
28
|
+
:user => "admin",
|
29
|
+
:password => "secret",
|
30
|
+
:host => "localhost",
|
31
|
+
:data_dir => "/usr/uv/db"
|
32
|
+
)
|
33
|
+
|
34
|
+
Unidata.open_connection do
|
35
|
+
# interact with Unidata here
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Or, you can manually open and close the connection yourself.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Unidata.open_connection
|
43
|
+
|
44
|
+
# interact with Unidata here
|
45
|
+
|
46
|
+
Unidata.close_connection
|
47
|
+
```
|
48
|
+
|
49
|
+
### Defining models:
|
25
50
|
|
26
51
|
```ruby
|
27
52
|
class Product < Unidata::Model
|
@@ -34,7 +59,7 @@ class Product < Unidata::Model
|
|
34
59
|
end
|
35
60
|
```
|
36
61
|
|
37
|
-
Creating records:
|
62
|
+
### Creating records:
|
38
63
|
|
39
64
|
```ruby
|
40
65
|
thingamajig = Product.new(
|
@@ -53,13 +78,13 @@ whatsit.available = Date.today
|
|
53
78
|
whatsit.save
|
54
79
|
```
|
55
80
|
|
56
|
-
|
81
|
+
### Retrieving records:
|
57
82
|
|
58
83
|
```ruby
|
59
84
|
product = Product.find(12345)
|
60
85
|
```
|
61
86
|
|
62
|
-
|
87
|
+
Or, you can just check if a record exists:
|
63
88
|
|
64
89
|
```ruby
|
65
90
|
Product.exists?(12345)
|
data/lib/unidata.rb
CHANGED
data/lib/unidata/connection.rb
CHANGED
@@ -24,6 +24,13 @@ module Unidata
|
|
24
24
|
@session = nil
|
25
25
|
end
|
26
26
|
|
27
|
+
def select(filename, condition="", list_number=0)
|
28
|
+
command = "SELECT #{filename} TO #{list_number}"
|
29
|
+
command << " WITH #{condition}" unless condition.empty?
|
30
|
+
@session.command(command).exec
|
31
|
+
SelectList.new(@session.select_list list_number)
|
32
|
+
end
|
33
|
+
|
27
34
|
def exists?(filename, record_id)
|
28
35
|
exists = false
|
29
36
|
|
data/lib/unidata/model.rb
CHANGED
@@ -23,6 +23,7 @@ module Unidata
|
|
23
23
|
def field(index, name, type=String, options={})
|
24
24
|
fields[name.to_sym] = Field.new(index, name, type, options)
|
25
25
|
define_attribute_accessor(name)
|
26
|
+
define_attribute_finder(name)
|
26
27
|
end
|
27
28
|
|
28
29
|
def to_unidata(instance)
|
@@ -64,6 +65,13 @@ module Unidata
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
68
|
+
def find_by(name, value)
|
69
|
+
field_number = "F#{fields[name.to_sym].index.first}"
|
70
|
+
connection.select(filename, "#{field_number} EQ \"#{value}\"").map do |id|
|
71
|
+
find(id)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
67
75
|
private
|
68
76
|
def define_attribute_accessor(attribute_name)
|
69
77
|
class_eval <<-end_eval
|
@@ -76,6 +84,14 @@ module Unidata
|
|
76
84
|
end
|
77
85
|
end_eval
|
78
86
|
end
|
87
|
+
|
88
|
+
def define_attribute_finder(attribute_name)
|
89
|
+
instance_eval <<-end_eval
|
90
|
+
def find_by_#{attribute_name}(value)
|
91
|
+
find_by(:#{attribute_name}, value)
|
92
|
+
end
|
93
|
+
end_eval
|
94
|
+
end
|
79
95
|
end
|
80
96
|
|
81
97
|
def initialize(attributes={})
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Unidata
|
2
|
+
class SelectList
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(uniselect_list, should_cache=false)
|
6
|
+
@uniselect_list = uniselect_list
|
7
|
+
@should_cache = should_cache
|
8
|
+
@cache = []
|
9
|
+
@exhausted = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def each &block
|
13
|
+
return [] if @exhausted && !@should_cache
|
14
|
+
if @exhausted
|
15
|
+
@cache.each &block
|
16
|
+
else
|
17
|
+
iterate &block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def iterate
|
24
|
+
until (id = @uniselect_list.next.to_s).empty? do
|
25
|
+
@cache << id if @should_cache
|
26
|
+
yield id
|
27
|
+
end
|
28
|
+
@exhausted = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/unidata/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -22,5 +22,15 @@ def package_local_constructor klass,*values
|
|
22
22
|
raise TypeError,"found no matching constructor for " + klass.to_s + "(" + value.class + ")"
|
23
23
|
end
|
24
24
|
|
25
|
+
class StubUniSelectList
|
26
|
+
def initialize(items)
|
27
|
+
@items = items.map{|item| item.to_s}
|
28
|
+
end
|
29
|
+
|
30
|
+
def next
|
31
|
+
@items.shift || ""
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
25
35
|
RSpec.configure do |config|
|
26
36
|
end
|
@@ -71,6 +71,33 @@ describe Unidata::Connection do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
describe '#select' do
|
75
|
+
before(:each) do
|
76
|
+
@session.stub(:command).and_return(double.as_null_object)
|
77
|
+
@session.stub(:select_list)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'executes the correct command' do
|
81
|
+
connection.open
|
82
|
+
|
83
|
+
@session.should_receive(:command).with('SELECT NAMES-FILE TO 0 WITH NAME EQ "JAMES,BILL"')
|
84
|
+
connection.select('NAMES-FILE', 'NAME EQ "JAMES,BILL"')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'fetchs the correct select list' do
|
88
|
+
connection.open
|
89
|
+
select_list = double
|
90
|
+
|
91
|
+
@session.should_receive(:select_list).with(5).and_return(select_list)
|
92
|
+
connection.select('NAMES-FILE', 'NAME EQ "JAMES,BILL"', 5)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns a SelectList' do
|
96
|
+
connection.open
|
97
|
+
connection.select('NAMES-FILE', 'NAME EQ "JAMES,BILL"').should be_a(Unidata::SelectList)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
74
101
|
describe '#exists?' do
|
75
102
|
before(:each) do
|
76
103
|
@file = double('UniFile', :close => nil, :read_field => nil)
|
data/spec/unidata/model_spec.rb
CHANGED
@@ -41,6 +41,11 @@ describe Unidata::Model do
|
|
41
41
|
obj.age = 25
|
42
42
|
obj.age.should == 25
|
43
43
|
end
|
44
|
+
|
45
|
+
it 'defines attribute finder for field' do
|
46
|
+
Record.should respond_to(:find_by_name)
|
47
|
+
Record.should respond_to(:find_by_status)
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
describe '.to_unidata' do
|
@@ -164,6 +169,67 @@ describe Unidata::Model do
|
|
164
169
|
end
|
165
170
|
end
|
166
171
|
|
172
|
+
describe '.find_by' do
|
173
|
+
before(:each) do
|
174
|
+
@connection = double
|
175
|
+
Unidata.stub(:connection).and_return(@connection)
|
176
|
+
|
177
|
+
records = {}
|
178
|
+
|
179
|
+
records['123'] = Unidata::UniDynArray.new
|
180
|
+
records['123'].replace 1, 'JOHN DOE'
|
181
|
+
records['123'].replace 2, 25
|
182
|
+
records['123'].replace 3, Date.to_unidata(Date.today)
|
183
|
+
records['123'].replace 4, 1, 'AWESOME COMPANY'
|
184
|
+
records['123'].replace 4, 2, 'MANAGER'
|
185
|
+
records['123'].replace 4, 3, 6_000_000
|
186
|
+
records['123'].replace 5, 'INACTIVE'
|
187
|
+
|
188
|
+
records['234'] = Unidata::UniDynArray.new
|
189
|
+
records['234'].replace 1, 'BILL JAMES'
|
190
|
+
records['234'].replace 2, 20
|
191
|
+
records['234'].replace 3, Date.to_unidata(Date.today)
|
192
|
+
records['234'].replace 4, 1, 'AWESOME COMPANY'
|
193
|
+
records['234'].replace 4, 2, 'SALES'
|
194
|
+
records['234'].replace 4, 3, 3_000_000
|
195
|
+
records['234'].replace 5, 'INACTIVE'
|
196
|
+
|
197
|
+
@connection.stub(:read).and_return{|file, id| records[id]}
|
198
|
+
|
199
|
+
select_list = Unidata::SelectList.new StubUniSelectList.new(['123', '234'])
|
200
|
+
@connection.stub(:select).and_return(select_list)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'should return the models found by attribute' do
|
204
|
+
records = Record.find_by_status('INACTIVE')
|
205
|
+
|
206
|
+
records[0].id.should == '123'
|
207
|
+
records[0].name.should == 'JOHN DOE'
|
208
|
+
records[0].age.should == 25
|
209
|
+
records[0].birth_date.should == Date.today
|
210
|
+
records[0].employer.should == 'AWESOME COMPANY'
|
211
|
+
records[0].job_title.should == 'MANAGER'
|
212
|
+
records[0].salary.should == BigDecimal.new('60_000.00')
|
213
|
+
records[0].status.should == 'INACTIVE'
|
214
|
+
|
215
|
+
records[1].id.should == '234'
|
216
|
+
records[1].name.should == 'BILL JAMES'
|
217
|
+
records[1].age.should == 20
|
218
|
+
records[1].birth_date.should == Date.today
|
219
|
+
records[1].employer.should == 'AWESOME COMPANY'
|
220
|
+
records[1].job_title.should == 'SALES'
|
221
|
+
records[1].salary.should == BigDecimal.new('30_000.00')
|
222
|
+
records[1].status.should == 'INACTIVE'
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should return an empty array if none are found' do
|
226
|
+
select_list = Unidata::SelectList.new StubUniSelectList.new([])
|
227
|
+
@connection.stub(:select).and_return(select_list)
|
228
|
+
|
229
|
+
Record.find_by_status('ACTIVE').should == []
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
167
233
|
describe '#initialize' do
|
168
234
|
it 'captures provied attributes' do
|
169
235
|
instance = Record.new(:id => '123', :name => 'John Doe', :status => 'inactive')
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Unidata::SelectList do
|
4
|
+
def create_list(items, should_cache=false)
|
5
|
+
list = StubUniSelectList.new(items)
|
6
|
+
Unidata::SelectList.new(list, should_cache)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:list) { create_list ['1', '2', '3'] }
|
10
|
+
|
11
|
+
describe '#each' do
|
12
|
+
it 'should yield each of the items in the select list' do
|
13
|
+
expect {|b| list.each &b }.to yield_successive_args '1', '2', '3'
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'without caching' do
|
17
|
+
it 'should only be able to iterate once' do
|
18
|
+
list.each{|i| i}
|
19
|
+
expect {|b| list.each &b }.not_to yield_control
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with caching' do
|
24
|
+
it 'should be able to iterate many times' do
|
25
|
+
list = create_list ['1', '2', '3'], true
|
26
|
+
list.each{|i| i}
|
27
|
+
expect {|b| list.each &b }.to yield_successive_args '1', '2', '3'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have the enumerable methods' do
|
33
|
+
list.map{|i| ":#{i}:" }.should == [':1:', ':2:', ':3:']
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: unidata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jeremy Israelsen
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/unidata/extensions/string.rb
|
78
78
|
- lib/unidata/field.rb
|
79
79
|
- lib/unidata/model.rb
|
80
|
+
- lib/unidata/select_list.rb
|
80
81
|
- lib/unidata/version.rb
|
81
82
|
- LICENSE
|
82
83
|
- README.md
|
@@ -84,6 +85,7 @@ files:
|
|
84
85
|
- spec/unidata/connection_spec.rb
|
85
86
|
- spec/unidata/field_spec.rb
|
86
87
|
- spec/unidata/model_spec.rb
|
88
|
+
- spec/unidata/select_list_spec.rb
|
87
89
|
- spec/unidata_spec.rb
|
88
90
|
homepage: http://github.com/jisraelsen/unidata
|
89
91
|
licenses: []
|
@@ -114,5 +116,6 @@ test_files:
|
|
114
116
|
- spec/unidata/connection_spec.rb
|
115
117
|
- spec/unidata/field_spec.rb
|
116
118
|
- spec/unidata/model_spec.rb
|
119
|
+
- spec/unidata/select_list_spec.rb
|
117
120
|
- spec/unidata_spec.rb
|
118
121
|
...
|