unidata 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.md +99 -0
- data/lib/unidata.rb +33 -0
- data/lib/unidata/connection.rb +111 -0
- data/lib/unidata/extensions.rb +6 -0
- data/lib/unidata/extensions/big_decimal.rb +17 -0
- data/lib/unidata/extensions/date.rb +19 -0
- data/lib/unidata/extensions/float.rb +17 -0
- data/lib/unidata/extensions/integer.rb +17 -0
- data/lib/unidata/extensions/string.rb +17 -0
- data/lib/unidata/extensions/time.rb +17 -0
- data/lib/unidata/field.rb +19 -0
- data/lib/unidata/model.rb +106 -0
- data/lib/unidata/version.rb +3 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unidata/connection_spec.rb +237 -0
- data/spec/unidata/field_spec.rb +113 -0
- data/spec/unidata/model_spec.rb +185 -0
- data/spec/unidata_spec.rb +24 -0
- metadata +134 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jeremy Israelsen, TotalCareAuto
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
UniData ORM
|
2
|
+
===========
|
3
|
+
|
4
|
+
A simple ORM for Rocket's UniData database.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'unidata'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install unidata
|
20
|
+
|
21
|
+
Usage
|
22
|
+
-----
|
23
|
+
|
24
|
+
Model definition:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
class Product < Unidata::Model
|
28
|
+
self.filename = 'PRODUCT'
|
29
|
+
|
30
|
+
field 1, :name, String
|
31
|
+
field 2, :description # type is optional (defaults to String)
|
32
|
+
field 3, :cost, Float
|
33
|
+
field 4, :available_on, Date
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
Creating records:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
thingamajig = Product.new(
|
41
|
+
:id => 12345,
|
42
|
+
:name =>'Thingamajig',
|
43
|
+
:cost => 125.99,
|
44
|
+
:available => Date.today
|
45
|
+
)
|
46
|
+
thingamajig.save
|
47
|
+
|
48
|
+
whatsit = Product.new
|
49
|
+
whatsit.id = 12346
|
50
|
+
whatsit.name = 'Whatsit'
|
51
|
+
whatsit.cost = 999.99
|
52
|
+
whatsit.available = Date.today
|
53
|
+
whatsit.save
|
54
|
+
```
|
55
|
+
|
56
|
+
Record retrieval:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
product = Product.find(12345)
|
60
|
+
```
|
61
|
+
|
62
|
+
Checking if a record exists:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
Product.exists?(12345)
|
66
|
+
```
|
67
|
+
|
68
|
+
Contributing
|
69
|
+
------------
|
70
|
+
|
71
|
+
Pull requests are welcome. Just make sure to include tests!
|
72
|
+
|
73
|
+
To run tests, install some dependencies:
|
74
|
+
|
75
|
+
```bash
|
76
|
+
bundle install
|
77
|
+
```
|
78
|
+
|
79
|
+
Then, run tests with:
|
80
|
+
|
81
|
+
```bash
|
82
|
+
rake spec
|
83
|
+
```
|
84
|
+
|
85
|
+
Or, If you want to check coverage:
|
86
|
+
|
87
|
+
```bash
|
88
|
+
COVERAGE=on rake spec
|
89
|
+
```
|
90
|
+
|
91
|
+
Issues
|
92
|
+
------
|
93
|
+
|
94
|
+
Please use GitHub's [issue tracker](http://github.com/totalcareauto/unidata/issues).
|
95
|
+
|
96
|
+
Authors
|
97
|
+
-------
|
98
|
+
|
99
|
+
[Jeremy Israelsen](http://github.com/jisraelsen)
|
data/lib/unidata.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'udjrb'
|
2
|
+
require 'time'
|
3
|
+
require 'date'
|
4
|
+
require 'bigdecimal'
|
5
|
+
require 'unidata/extensions'
|
6
|
+
require 'unidata/connection'
|
7
|
+
require 'unidata/field'
|
8
|
+
require 'unidata/model'
|
9
|
+
require "unidata/version"
|
10
|
+
|
11
|
+
module Unidata
|
12
|
+
class << self
|
13
|
+
attr_reader :connection
|
14
|
+
|
15
|
+
def prepare_connection(config={})
|
16
|
+
@connection = Connection.new(config[:user], config[:password], config[:host], config[:data_dir])
|
17
|
+
end
|
18
|
+
|
19
|
+
def open_connection
|
20
|
+
begin
|
21
|
+
@connection.open
|
22
|
+
yield if block_given?
|
23
|
+
ensure
|
24
|
+
close_connection if block_given?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def close_connection
|
29
|
+
@connection.close
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Unidata
|
2
|
+
class Connection
|
3
|
+
attr_reader :user, :password, :host, :data_dir
|
4
|
+
|
5
|
+
def initialize(user, password, host, data_dir)
|
6
|
+
@user = user
|
7
|
+
@password = password
|
8
|
+
@host = host
|
9
|
+
@data_dir = data_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def open?
|
13
|
+
!@session.nil? && @session.is_active
|
14
|
+
end
|
15
|
+
|
16
|
+
def open
|
17
|
+
@session = UDJrb::Session.new user, password, host, data_dir
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
@session.disconnect if @session
|
22
|
+
@session = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def exists?(filename, record_id)
|
26
|
+
exists = false
|
27
|
+
|
28
|
+
open_file(filename) do |file|
|
29
|
+
begin
|
30
|
+
file.read_field(record_id, 0)
|
31
|
+
exists = true
|
32
|
+
rescue Java::AsjavaUniobjects::UniFileException
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
exists
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(filename, record_id)
|
40
|
+
record = nil
|
41
|
+
|
42
|
+
open_file(filename) do |file|
|
43
|
+
begin
|
44
|
+
record = Java::AsjavaUniclientlibs::UniDynArray.new(file.read(record_id))
|
45
|
+
rescue Java::AsjavaUniobjects::UniFileException
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
record
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_field(filename, record_id, field)
|
53
|
+
value = nil
|
54
|
+
|
55
|
+
open_file(filename) do |file|
|
56
|
+
begin
|
57
|
+
value = file.read_field(record_id, field).to_s
|
58
|
+
rescue Java::AsjavaUniobjects::UniFileException
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
value
|
63
|
+
end
|
64
|
+
|
65
|
+
def write(filename, record_id, record)
|
66
|
+
record = record.to_unidata unless record.kind_of?(Java::AsjavaUniclientlibs::UniDynArray)
|
67
|
+
|
68
|
+
open_file(filename) do |file|
|
69
|
+
file.write(record_id, record)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def write_field(filename, record_id, value, field)
|
74
|
+
open_file(filename) do |file|
|
75
|
+
file.write_field(record_id, value, field)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def with_record_lock(filename, record_id, lock_flag=1)
|
80
|
+
open_file(filename) do |file|
|
81
|
+
retry_count = 0
|
82
|
+
begin
|
83
|
+
file.lock_record(record_id, lock_flag)
|
84
|
+
yield
|
85
|
+
rescue Java::AsjavaUniobjects::UniFileException
|
86
|
+
# try to obtain a record lock at most 3 times, then give up
|
87
|
+
if retry_count < 2
|
88
|
+
sleep 5
|
89
|
+
|
90
|
+
retry_count += 1
|
91
|
+
retry
|
92
|
+
else
|
93
|
+
raise
|
94
|
+
end
|
95
|
+
ensure
|
96
|
+
file.unlock_record(record_id)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def open_file(filename)
|
103
|
+
begin
|
104
|
+
file = @session.open filename
|
105
|
+
yield file
|
106
|
+
ensure
|
107
|
+
file.close
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Unidata
|
2
|
+
module Extensions
|
3
|
+
module BigDecimal
|
4
|
+
def to_unidata(value)
|
5
|
+
(value * 100).to_i
|
6
|
+
end
|
7
|
+
|
8
|
+
def from_unidata(value)
|
9
|
+
::BigDecimal.new(value.to_s) / 100
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class BigDecimal
|
16
|
+
extend Unidata::Extensions::BigDecimal
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Unidata
|
2
|
+
module Extensions
|
3
|
+
module Date
|
4
|
+
PICK_EPOCH = ::Date.parse('1968-01-01')
|
5
|
+
|
6
|
+
def to_unidata(value)
|
7
|
+
(value - PICK_EPOCH).to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def from_unidata(value)
|
11
|
+
PICK_EPOCH + value.to_i
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Date
|
18
|
+
extend Unidata::Extensions::Date
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Unidata
|
2
|
+
module Extensions
|
3
|
+
module Float
|
4
|
+
def to_unidata(value)
|
5
|
+
::BigDecimal.to_unidata(value)
|
6
|
+
end
|
7
|
+
|
8
|
+
def from_unidata(value)
|
9
|
+
::BigDecimal.from_unidata(value).to_f
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Float
|
16
|
+
extend Unidata::Extensions::Float
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Unidata
|
2
|
+
module Extensions
|
3
|
+
module Time
|
4
|
+
def to_unidata(value)
|
5
|
+
::Date.to_unidata(value.to_date)
|
6
|
+
end
|
7
|
+
|
8
|
+
def from_unidata(value)
|
9
|
+
::Date.from_unidata(value).to_time
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Time
|
16
|
+
extend Unidata::Extensions::Time
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Unidata
|
2
|
+
class Field
|
3
|
+
attr_reader :index, :name, :type, :formatter
|
4
|
+
|
5
|
+
def initialize(index, name, type=String)
|
6
|
+
@index = [*index]
|
7
|
+
@name = name
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_unidata(value)
|
12
|
+
type.to_unidata(value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def from_unidata(value)
|
16
|
+
type.from_unidata(value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Unidata
|
2
|
+
class Model
|
3
|
+
class << self
|
4
|
+
attr_accessor :filename
|
5
|
+
|
6
|
+
def connection
|
7
|
+
Unidata.connection
|
8
|
+
end
|
9
|
+
|
10
|
+
def fields
|
11
|
+
unless @fields
|
12
|
+
@fields = {}
|
13
|
+
field(0, :id)
|
14
|
+
end
|
15
|
+
|
16
|
+
@fields
|
17
|
+
end
|
18
|
+
|
19
|
+
def field?(name)
|
20
|
+
fields.keys.include?(name.to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
def field(index, name, type=String)
|
24
|
+
fields[name.to_sym] = Field.new(index, name, type)
|
25
|
+
define_attribute_accessor(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_unidata(instance)
|
29
|
+
record = Java::AsjavaUniclientlibs::UniDynArray.new
|
30
|
+
|
31
|
+
instance.attributes.each do |key, value|
|
32
|
+
next if key == :id
|
33
|
+
|
34
|
+
field = fields[key]
|
35
|
+
record.replace *field.index, field.to_unidata(value)
|
36
|
+
end
|
37
|
+
|
38
|
+
record
|
39
|
+
end
|
40
|
+
|
41
|
+
def from_unidata(record)
|
42
|
+
instance = new
|
43
|
+
|
44
|
+
fields.each do |key, field|
|
45
|
+
next if key == :id
|
46
|
+
|
47
|
+
instance.send(
|
48
|
+
"#{key}=",
|
49
|
+
field.from_unidata(record.extract(*field.index).to_s)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
instance
|
54
|
+
end
|
55
|
+
|
56
|
+
def exists?(id)
|
57
|
+
connection.exists?(filename, id)
|
58
|
+
end
|
59
|
+
|
60
|
+
def find(id)
|
61
|
+
record = connection.read(filename, id)
|
62
|
+
|
63
|
+
instance = from_unidata(record)
|
64
|
+
instance.id = id
|
65
|
+
instance
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def define_attribute_accessor(attribute_name)
|
70
|
+
class_eval <<-end_eval
|
71
|
+
def #{attribute_name}
|
72
|
+
read_attribute(:#{attribute_name})
|
73
|
+
end
|
74
|
+
|
75
|
+
def #{attribute_name}=(value)
|
76
|
+
write_attribute(:#{attribute_name}, value)
|
77
|
+
end
|
78
|
+
end_eval
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
attr_reader :attributes
|
83
|
+
|
84
|
+
def initialize(attributes={})
|
85
|
+
@attributes = {}
|
86
|
+
attributes.each do |key,value|
|
87
|
+
next unless self.class.field?(key.to_sym)
|
88
|
+
@attributes[key.to_sym] = value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def save
|
93
|
+
record = self.class.to_unidata(self)
|
94
|
+
self.class.connection.write(self.class.filename, id, record)
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def read_attribute(attribute_name)
|
99
|
+
@attributes[attribute_name.to_sym]
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_attribute(attribute_name, value)
|
103
|
+
@attributes[attribute_name.to_sym] = value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
if ENV['COVERAGE']
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter '/spec/'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'rspec'
|
9
|
+
require 'unidata'
|
10
|
+
|
11
|
+
def package_local_constructor klass,*values
|
12
|
+
constructors = klass.java_class.declared_constructors
|
13
|
+
constructors.each do |c|
|
14
|
+
c.accessible = true
|
15
|
+
begin
|
16
|
+
return c.new_instance(*values).to_java
|
17
|
+
rescue TypeError
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
raise TypeError,"found no matching constructor for " + klass.to_s + "(" + value.class + ")"
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Unidata::Connection do
|
4
|
+
let(:connection) { Unidata::Connection.new('test', 'secret', 'localhost', 'tmp') }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'captures and assigns arguments' do
|
8
|
+
connection.user.should == 'test'
|
9
|
+
connection.password.should == 'secret'
|
10
|
+
connection.host.should == 'localhost'
|
11
|
+
connection.data_dir.should == 'tmp'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#open?' do
|
16
|
+
context 'with existing active session' do
|
17
|
+
it 'returns true' do
|
18
|
+
UDJrb::Session.stub(:new).and_return(double('UDJrb::Session', :is_active => true))
|
19
|
+
connection.open
|
20
|
+
connection.open?.should == true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with existing inactive session' do
|
25
|
+
it 'returns false' do
|
26
|
+
UDJrb::Session.stub(:new).and_return(double('UDJrb::Session', :is_active => false))
|
27
|
+
connection.open
|
28
|
+
connection.open?.should == false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'without existing session' do
|
33
|
+
it 'returns false' do
|
34
|
+
connection.open?.should == false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#open' do
|
40
|
+
it 'creates a new session with config params' do
|
41
|
+
UDJrb::Session.should_receive(:new).with(connection.user, connection.password, connection.host, connection.data_dir)
|
42
|
+
connection.open
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#close' do
|
47
|
+
it 'disconnects the session' do
|
48
|
+
session = double('UDJrb::Session', :disconnect => nil)
|
49
|
+
UDJrb::Session.stub(:new).and_return(session)
|
50
|
+
connection.open
|
51
|
+
|
52
|
+
session.should_receive(:disconnect)
|
53
|
+
connection.close
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#exists?' do
|
58
|
+
before(:each) do
|
59
|
+
@file = double('UniFile', :close => nil, :read_field => nil)
|
60
|
+
@session = double('UDJrb::Session', :open => @file)
|
61
|
+
|
62
|
+
UDJrb::Session.stub(:new).and_return(@session)
|
63
|
+
connection.open
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'opens file with filename' do
|
67
|
+
@session.should_receive(:open).with('TEST')
|
68
|
+
connection.exists?('TEST', 123)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'reads record_id field from file' do
|
72
|
+
@file.should_receive(:read_field).with(123, 0)
|
73
|
+
connection.exists?('TEST', 123)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'closes file' do
|
77
|
+
@file.should_receive(:close)
|
78
|
+
connection.exists?('TEST', 123)
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when file has given record_id' do
|
82
|
+
it 'returns true' do
|
83
|
+
@file.stub(:read_field).and_return('123')
|
84
|
+
connection.exists?('TEST', 123).should == true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when file has no given record_id' do
|
89
|
+
it 'returns false' do
|
90
|
+
uni_file_exception = package_local_constructor Java::AsjavaUniobjects::UniFileException
|
91
|
+
|
92
|
+
@file.stub(:read_field).and_raise(uni_file_exception)
|
93
|
+
connection.exists?('TEST', 123).should == false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#read' do
|
99
|
+
before(:each) do
|
100
|
+
@file = double('UniFile', :close => nil, :read => nil)
|
101
|
+
@session = double('UDJrb::Session', :open => @file)
|
102
|
+
|
103
|
+
UDJrb::Session.stub(:new).and_return(@session)
|
104
|
+
connection.open
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'opens file in session' do
|
108
|
+
@session.should_receive(:open).with('TEST')
|
109
|
+
connection.read('TEST', 123)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'reads record from file' do
|
113
|
+
@file.should_receive(:read).with(123)
|
114
|
+
connection.read('TEST', 123)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'closes file' do
|
118
|
+
@file.should_receive(:close)
|
119
|
+
connection.read('TEST', 123)
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when record exists' do
|
123
|
+
it 'returns record as a Java::AsjavaUniclientlibs::UniDynArray' do
|
124
|
+
@file.stub(:read).and_return('')
|
125
|
+
connection.read('TEST', 123).should be_kind_of(Java::AsjavaUniclientlibs::UniDynArray)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when record does not exist' do
|
130
|
+
it 'returns nil' do
|
131
|
+
uni_file_exception = package_local_constructor Java::AsjavaUniobjects::UniFileException
|
132
|
+
|
133
|
+
@file.stub(:read).and_raise(uni_file_exception)
|
134
|
+
connection.read('TEST', 123).should be_nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '#read_field' do
|
140
|
+
before(:each) do
|
141
|
+
@file = double('UniFile', :close => nil, :read_field => nil)
|
142
|
+
@session = double('UDJrb::Session', :open => @file)
|
143
|
+
|
144
|
+
UDJrb::Session.stub(:new).and_return(@session)
|
145
|
+
connection.open
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'opens file with filename' do
|
149
|
+
@session.should_receive(:open).with('TEST')
|
150
|
+
connection.read_field('TEST', 123, 5)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'reads field from file' do
|
154
|
+
@file.should_receive(:read_field).with(123, 5)
|
155
|
+
connection.read_field('TEST', 123, 5)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'closes file' do
|
159
|
+
@file.should_receive(:close)
|
160
|
+
connection.read_field('TEST', 123, 5)
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'when field exists' do
|
164
|
+
it 'returns value as a String' do
|
165
|
+
@file.stub(:read_field).and_return(43245)
|
166
|
+
connection.read_field('TEST', 123, 5).should == '43245'
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when field does not exist' do
|
171
|
+
it 'returns nil' do
|
172
|
+
uni_file_exception = package_local_constructor Java::AsjavaUniobjects::UniFileException
|
173
|
+
|
174
|
+
@file.stub(:read_field).and_raise(uni_file_exception)
|
175
|
+
connection.read_field('TEST', 123, 5).should be_nil
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '#write' do
|
181
|
+
before(:each) do
|
182
|
+
@file = double('UniFile', :close => nil, :write => nil)
|
183
|
+
@session = double('UDJrb::Session', :open => @file)
|
184
|
+
@record = Java::AsjavaUniclientlibs::UniDynArray.new
|
185
|
+
|
186
|
+
UDJrb::Session.stub(:new).and_return(@session)
|
187
|
+
connection.open
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'opens file in session' do
|
191
|
+
@session.should_receive(:open).with('TEST')
|
192
|
+
connection.write('TEST', 123, @record)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'calls to_unidata on record if record not a Java::AsjavaUniclientlibs::UniDynArray' do
|
196
|
+
record = double('Record')
|
197
|
+
record.should_receive(:to_unidata).and_return(Java::AsjavaUniclientlibs::UniDynArray.new)
|
198
|
+
|
199
|
+
connection.write('TEST', 123, record)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'writes record to file' do
|
203
|
+
@file.should_receive(:write).with(123, @record)
|
204
|
+
connection.write('TEST', 123, @record)
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'closes file' do
|
208
|
+
@file.should_receive(:close)
|
209
|
+
connection.write('TEST', 123, @record)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe '#write_field' do
|
214
|
+
before(:each) do
|
215
|
+
@file = double('UniFile', :close => nil, :write_field => nil)
|
216
|
+
@session = double('UDJrb::Session', :open => @file)
|
217
|
+
|
218
|
+
UDJrb::Session.stub(:new).and_return(@session)
|
219
|
+
connection.open
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'opens file with filename' do
|
223
|
+
@session.should_receive(:open).with('TEST')
|
224
|
+
connection.write_field('TEST', 123, 'value', 5)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'writes field to file' do
|
228
|
+
@file.should_receive(:write_field).with(123, 'value', 5)
|
229
|
+
connection.write_field('TEST', 123, 'value', 5)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'closes file' do
|
233
|
+
@file.should_receive(:close)
|
234
|
+
connection.write_field('TEST', 123, 'value', 5)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Unidata::Field do
|
4
|
+
subject { Unidata::Field }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'captures and assigns arguments' do
|
8
|
+
field = subject.new(1, :date, Date)
|
9
|
+
field.index.should == [1]
|
10
|
+
field.name.should == :date
|
11
|
+
field.type.should == Date
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'accepts multivalued indexes' do
|
15
|
+
field = subject.new([1,2], :name)
|
16
|
+
field.index.should == [1,2]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'defaults type to String' do
|
20
|
+
field = subject.new(2, :name)
|
21
|
+
field.type.should == String
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#to_unidata' do
|
26
|
+
context 'when type is Time' do
|
27
|
+
it 'converts value to pick time' do
|
28
|
+
field = subject.new(1, :created_at, Time)
|
29
|
+
field.to_unidata(Time.parse('2012-04-02 12:34:00')).should == 16163
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when type is Date' do
|
34
|
+
it 'converts value to pick time' do
|
35
|
+
field = subject.new(1, :created_on, Date)
|
36
|
+
field.to_unidata(Date.parse('2012-04-03')).should == 16164
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when type is String' do
|
41
|
+
it 'upcases value' do
|
42
|
+
field = subject.new(1, :name, String)
|
43
|
+
field.to_unidata('John Doe').should == 'JOHN DOE'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when type is Float' do
|
48
|
+
it 'multiplies value by 100 and converts to an integer' do
|
49
|
+
field = subject.new(1, :price, Float)
|
50
|
+
field.to_unidata(123.32).should == 12332
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when type is BigDecimal' do
|
55
|
+
it 'multiplies value by 100 and converts to an integer' do
|
56
|
+
field = subject.new(1, :price, BigDecimal)
|
57
|
+
field.to_unidata(BigDecimal.new('123.32')).should == 12332
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when type is Integer' do
|
62
|
+
it 'does nothing' do
|
63
|
+
field = subject.new(1, :age, Integer)
|
64
|
+
field.to_unidata(45).should == 45
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#from_unidata' do
|
70
|
+
context 'when type is Time' do
|
71
|
+
it 'converts value from pick time' do
|
72
|
+
field = subject.new(1, :created_at, Time)
|
73
|
+
field.from_unidata(16163).should == Time.parse('2012-04-02 00:00:00')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when type is Date' do
|
78
|
+
it 'converts value from pick time' do
|
79
|
+
field = subject.new(1, :created_on, Date)
|
80
|
+
field.from_unidata(16164).should == Date.parse('2012-04-03')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when type is String' do
|
85
|
+
it 'does nothing' do
|
86
|
+
field = subject.new(1, :name, String)
|
87
|
+
field.from_unidata('JOHN DOE').should == 'JOHN DOE'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when type is Float' do
|
92
|
+
it 'converts value to Float and divides by 100' do
|
93
|
+
field = subject.new(1, :price, Float)
|
94
|
+
field.from_unidata(12332).should == 123.32
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when type is BigDecimal' do
|
99
|
+
it 'converts value to BigDecimal and divides by 100' do
|
100
|
+
field = subject.new(1, :price, BigDecimal)
|
101
|
+
field.from_unidata(12332).should == BigDecimal.new('123.32')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when type is Integer' do
|
106
|
+
it 'converts to an Integer' do
|
107
|
+
field = subject.new(1, :age, Integer)
|
108
|
+
field.from_unidata('45').should == 45
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Unidata::Model do
|
4
|
+
subject { Unidata::Model }
|
5
|
+
|
6
|
+
class Record < Unidata::Model
|
7
|
+
self.filename = 'TEST'
|
8
|
+
|
9
|
+
field 1, :name
|
10
|
+
field 2, :age, Integer
|
11
|
+
field 3, :birth_date, Date
|
12
|
+
field [4,1], :employer
|
13
|
+
field [4,2], :job_title
|
14
|
+
field [4,3], :salary, BigDecimal
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.connection' do
|
18
|
+
it 'returns the Unidata connection' do
|
19
|
+
Unidata.stub('connection').and_return(double('connection'))
|
20
|
+
subject.connection.should == Unidata.connection
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.field' do
|
25
|
+
it 'adds Field with given index, name, and type to fields hash' do
|
26
|
+
field = Record.fields[:age]
|
27
|
+
field.index.should == [2]
|
28
|
+
field.name.should == :age
|
29
|
+
field.type.should == Integer
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'defines attribute reader/writer for field' do
|
33
|
+
obj = Record.new
|
34
|
+
obj.age = 25
|
35
|
+
obj.age.should == 25
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '.to_unidata' do
|
40
|
+
before(:each) do
|
41
|
+
@obj = Record.new(
|
42
|
+
:id => 1234,
|
43
|
+
:name => 'John Doe',
|
44
|
+
:age => 25,
|
45
|
+
:birth_date => Date.today,
|
46
|
+
:employer => 'Awesome Company',
|
47
|
+
:job_title => 'Manager',
|
48
|
+
:salary => BigDecimal.new('60_000.00')
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'converts model to UniDynArray' do
|
53
|
+
record = Record.to_unidata(@obj)
|
54
|
+
record.extract(1).to_s.should == 'JOHN DOE'
|
55
|
+
record.extract(2).to_s.should == '25'
|
56
|
+
record.extract(3).to_s.should == Date.to_unidata(Date.today).to_s
|
57
|
+
record.extract(4, 1).to_s.should == 'AWESOME COMPANY'
|
58
|
+
record.extract(4, 2).to_s.should == 'MANAGER'
|
59
|
+
record.extract(4, 3).to_s.should == '6000000'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'skips id field' do
|
63
|
+
record = Record.to_unidata(@obj)
|
64
|
+
record.extract(0).to_s.should == ''
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.from_unidata' do
|
69
|
+
before(:each) do
|
70
|
+
@record = Java::AsjavaUniclientlibs::UniDynArray.new
|
71
|
+
@record.replace 0, 123
|
72
|
+
@record.replace 1, 'JOHN DOE'
|
73
|
+
@record.replace 2, 25
|
74
|
+
@record.replace 3, Date.to_unidata(Date.today)
|
75
|
+
@record.replace 4, 1, 'AWESOME COMPANY'
|
76
|
+
@record.replace 4, 2, 'MANAGER'
|
77
|
+
@record.replace 4, 3, 6_000_000
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'converts UniDynArray to model' do
|
81
|
+
obj = Record.from_unidata(@record)
|
82
|
+
obj.name.should == 'JOHN DOE'
|
83
|
+
obj.age.should == 25
|
84
|
+
obj.birth_date.should == Date.today
|
85
|
+
obj.employer.should == 'AWESOME COMPANY'
|
86
|
+
obj.job_title.should == 'MANAGER'
|
87
|
+
obj.salary.should == BigDecimal.new('60_000.00')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'skips id field' do
|
91
|
+
obj = Record.from_unidata(@record)
|
92
|
+
obj.id.should be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '.exists?' do
|
97
|
+
before(:each) do
|
98
|
+
@connection = double('connection')
|
99
|
+
@connection.stub(:exists?).with('TEST', 123).and_return(true)
|
100
|
+
@connection.stub(:exists?).with('TEST', 234).and_return(false)
|
101
|
+
|
102
|
+
Unidata.stub(:connection).and_return(@connection)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns true if record with id exists in file' do
|
106
|
+
Record.exists?(123).should == true
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'returns false if record with id does not exist in file' do
|
110
|
+
Record.exists?(234).should == false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '.find' do
|
115
|
+
before(:each) do
|
116
|
+
@record = Java::AsjavaUniclientlibs::UniDynArray.new
|
117
|
+
@record.replace 1, 'JOHN DOE'
|
118
|
+
@record.replace 2, 25
|
119
|
+
@record.replace 3, Date.to_unidata(Date.today)
|
120
|
+
@record.replace 4, 1, 'AWESOME COMPANY'
|
121
|
+
@record.replace 4, 2, 'MANAGER'
|
122
|
+
@record.replace 4, 3, 6_000_000
|
123
|
+
|
124
|
+
@connection = double('connection', :read => @record)
|
125
|
+
Unidata.stub(:connection).and_return(@connection)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'reads record from file' do
|
129
|
+
@connection.should_receive(:read).with('TEST', 123).and_return(@record)
|
130
|
+
Record.find(123)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'returns model' do
|
134
|
+
obj = Record.find(123)
|
135
|
+
obj.id.should == 123
|
136
|
+
obj.name.should == 'JOHN DOE'
|
137
|
+
obj.age.should == 25
|
138
|
+
obj.birth_date.should == Date.today
|
139
|
+
obj.employer.should == 'AWESOME COMPANY'
|
140
|
+
obj.job_title.should == 'MANAGER'
|
141
|
+
obj.salary.should == BigDecimal.new('60_000.00')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#initialize' do
|
146
|
+
it 'captures provied attributes' do
|
147
|
+
instance = Record.new(:id => 123, :name => 'John Doe')
|
148
|
+
instance.attributes.should == { :id => 123, :name => 'John Doe' }
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'ignores attributes that are not defined in fields' do
|
152
|
+
instance = Record.new(:id => 123, :name => 'John Doe', :nickname => 'J-Dog')
|
153
|
+
instance.attributes.should == { :id => 123, :name => 'John Doe' }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#save' do
|
158
|
+
it 'writes record to file' do
|
159
|
+
connection = double('connection', :write => nil)
|
160
|
+
Unidata.stub(:connection).and_return(connection)
|
161
|
+
|
162
|
+
obj = Record.new(
|
163
|
+
:id => 1234,
|
164
|
+
:name => 'John Doe',
|
165
|
+
:age => 25,
|
166
|
+
:birth_date => Date.today,
|
167
|
+
:employer => 'Awesome Company',
|
168
|
+
:job_title => 'Manager',
|
169
|
+
:salary => BigDecimal.new('60_000.00')
|
170
|
+
)
|
171
|
+
|
172
|
+
record = Java::AsjavaUniclientlibs::UniDynArray.new
|
173
|
+
record.replace 1, 'JOHN DOE'
|
174
|
+
record.replace 2, 25
|
175
|
+
record.replace 3, Date.to_unidata(Date.today)
|
176
|
+
record.replace 4, 1, 'AWESOME COMPANY'
|
177
|
+
record.replace 4, 2, 'MANAGER'
|
178
|
+
record.replace 4, 3, 6_000_000
|
179
|
+
|
180
|
+
connection.should_receive(:write).with('TEST', 1234, record)
|
181
|
+
obj.save
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Unidata do
|
4
|
+
before(:each) do
|
5
|
+
@config = { :user => 'test', :password => 'secret', :host => 'localhost', :data_dir => 'testdir' }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.prepare_connection' do
|
9
|
+
it 'prepares a unidata connection with config options' do
|
10
|
+
Unidata.prepare_connection @config
|
11
|
+
|
12
|
+
Unidata.connection.should be_kind_of(Unidata::Connection)
|
13
|
+
Unidata.connection.user.should == @config[:user]
|
14
|
+
Unidata.connection.password.should == @config[:password]
|
15
|
+
Unidata.connection.host.should == @config[:host]
|
16
|
+
Unidata.connection.data_dir.should == @config[:data_dir]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should not open the connection' do
|
20
|
+
Unidata.prepare_connection @config
|
21
|
+
Unidata.connection.should_not be_open
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unidata
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeremy Israelsen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: udjrb
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.0.3
|
21
|
+
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.3
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :runtime
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :development
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.10'
|
53
|
+
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '2.10'
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :development
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: simplecov
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.6'
|
69
|
+
none: false
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0.6'
|
75
|
+
none: false
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
description: A simple ORM for Rocket's UniData database
|
79
|
+
email:
|
80
|
+
- jisraelsen@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- lib/unidata.rb
|
86
|
+
- lib/unidata/connection.rb
|
87
|
+
- lib/unidata/extensions.rb
|
88
|
+
- lib/unidata/extensions/big_decimal.rb
|
89
|
+
- lib/unidata/extensions/date.rb
|
90
|
+
- lib/unidata/extensions/float.rb
|
91
|
+
- lib/unidata/extensions/integer.rb
|
92
|
+
- lib/unidata/extensions/string.rb
|
93
|
+
- lib/unidata/extensions/time.rb
|
94
|
+
- lib/unidata/field.rb
|
95
|
+
- lib/unidata/model.rb
|
96
|
+
- lib/unidata/version.rb
|
97
|
+
- LICENSE
|
98
|
+
- README.md
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/unidata/connection_spec.rb
|
101
|
+
- spec/unidata/field_spec.rb
|
102
|
+
- spec/unidata/model_spec.rb
|
103
|
+
- spec/unidata_spec.rb
|
104
|
+
homepage: http://github.com/totalcareauto/unidata
|
105
|
+
licenses: []
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
none: false
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
none: false
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 1.8.24
|
125
|
+
signing_key:
|
126
|
+
specification_version: 3
|
127
|
+
summary: A simple ORM for Rocket's UniData database
|
128
|
+
test_files:
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
- spec/unidata/connection_spec.rb
|
131
|
+
- spec/unidata/field_spec.rb
|
132
|
+
- spec/unidata/model_spec.rb
|
133
|
+
- spec/unidata_spec.rb
|
134
|
+
...
|