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 CHANGED
@@ -1,4 +1,4 @@
1
- UniData ORM [![Build Status](https://secure.travis-ci.org/jisraelsen/unidata.png?branch=master)](http://travis-ci.org/jisraelsen/unidata)
1
+ UniData ORM [![Build Status](https://secure.travis-ci.org/jisraelsen/unidata.png?branch=master)](http://travis-ci.org/jisraelsen/unidata) [![Code Climate](https://codeclimate.com/badge.png)](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
- Model definition:
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
- Record retrieval:
81
+ ### Retrieving records:
57
82
 
58
83
  ```ruby
59
84
  product = Product.find(12345)
60
85
  ```
61
86
 
62
- Checking if a record exists:
87
+ Or, you can just check if a record exists:
63
88
 
64
89
  ```ruby
65
90
  Product.exists?(12345)
@@ -1,6 +1,7 @@
1
1
  require 'java'
2
2
  require 'unidata/asjava.jar'
3
3
  require 'unidata/extensions'
4
+ require 'unidata/select_list'
4
5
  require 'unidata/connection'
5
6
  require 'unidata/field'
6
7
  require 'unidata/model'
@@ -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
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Unidata
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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)
@@ -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
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-07-25 00:00:00.000000000 Z
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
  ...