activerecord-nuodb-adapter 1.0.0.rc.1 → 1.0.0.rc.2
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.rdoc
CHANGED
@@ -4,6 +4,77 @@
|
|
4
4
|
|
5
5
|
This is the NuoDB ActiveRecord Adapter.
|
6
6
|
|
7
|
+
== RUNNING A SAMPLE APPLICATION
|
8
|
+
|
9
|
+
Let me walk you through the creation of a sample Ruby application to the point
|
10
|
+
of having it running against NuoDB...
|
11
|
+
|
12
|
+
Start up a minimal chorus as follows:
|
13
|
+
|
14
|
+
export NUODB_ROOT=/Users/Path/To/NuoDB
|
15
|
+
java -jar ${NUODB_ROOT}/jar/nuoagent.jar --broker &
|
16
|
+
${NUODB_ROOT}/bin/nuodb --chorus test --password bar --dba-user dba --dba-password baz --verbose debug --archive /var/tmp/nuodb --initialize --force &
|
17
|
+
${NUODB_ROOT}/bin/nuodb --chorus test --password bar --dba-user dba --dba-password baz &
|
18
|
+
|
19
|
+
Create a user in the database:
|
20
|
+
|
21
|
+
${NUODB_ROOT}/bin/nuosql test@localhost --user dba --password baz
|
22
|
+
> create user cloud password 'user';
|
23
|
+
> exit
|
24
|
+
|
25
|
+
Install our Gems; the following shows how to do this if you have copies
|
26
|
+
of the gems locally, but is easier if you install them from rubygems.org.
|
27
|
+
|
28
|
+
gem install nuodb-1.0.0.rc.2.gem
|
29
|
+
gem install activerecord-nuodb-adapter-1.0.0.rc.2.gem
|
30
|
+
|
31
|
+
Prepare a sample application:
|
32
|
+
|
33
|
+
rails new slambook
|
34
|
+
cd slambook/
|
35
|
+
|
36
|
+
Add the following Gems to your Gemfile:
|
37
|
+
|
38
|
+
gem 'nuodb', '=1.0.0.rc.2'
|
39
|
+
gem 'activerecord-nuodb-adapter', '=1.0.0.rc.2'
|
40
|
+
|
41
|
+
Update your config/database.yml file as follows:
|
42
|
+
|
43
|
+
development:
|
44
|
+
adapter: nuodb
|
45
|
+
database: test@localhost
|
46
|
+
username: cloud
|
47
|
+
password: user
|
48
|
+
schema: test
|
49
|
+
|
50
|
+
test:
|
51
|
+
adapter: nuodb
|
52
|
+
database: test@localhost
|
53
|
+
username: cloud
|
54
|
+
password: user
|
55
|
+
schema: test
|
56
|
+
|
57
|
+
production:
|
58
|
+
adapter: nuodb
|
59
|
+
database: test@localhost
|
60
|
+
username: cloud
|
61
|
+
password: user
|
62
|
+
schema: test
|
63
|
+
|
64
|
+
6. Build the application and prepare your databases:
|
65
|
+
|
66
|
+
bundle install
|
67
|
+
rake db:create
|
68
|
+
rake db:migrate
|
69
|
+
|
70
|
+
7. Start the Rails server:
|
71
|
+
|
72
|
+
bundle exec rails server
|
73
|
+
|
74
|
+
8. Open up your browser:
|
75
|
+
|
76
|
+
chrome http://localhost:3000
|
77
|
+
|
7
78
|
== BUILDING THE GEM
|
8
79
|
|
9
80
|
To compile and test run this command:
|
@@ -12,11 +83,11 @@ To compile and test run this command:
|
|
12
83
|
|
13
84
|
== INSTALLING THE GEM
|
14
85
|
|
15
|
-
gem install activerecord-nuodb-adapter-1.0.0.rc.
|
86
|
+
gem install activerecord-nuodb-adapter-1.0.0.rc.2.gem
|
16
87
|
|
17
88
|
Or from the source tree:
|
18
89
|
|
19
|
-
gem install pkg/activerecord-nuodb-adapter-1.0.0.rc.
|
90
|
+
gem install pkg/activerecord-nuodb-adapter-1.0.0.rc.2.gem
|
20
91
|
|
21
92
|
Or you can do this using Rake:
|
22
93
|
|
@@ -45,25 +116,57 @@ Run the tests:
|
|
45
116
|
|
46
117
|
Tag the product using tags per the SemVer specification; our tags have a v-prefix:
|
47
118
|
|
48
|
-
git tag -a v1.0.0-rc.
|
119
|
+
git tag -a v1.0.0-rc.2 -m "SemVer Version: v1.0.0-rc.2"
|
49
120
|
git push --tags
|
50
121
|
|
51
122
|
If you make a mistake, take it back quickly:
|
52
123
|
|
53
|
-
git tag -d v1.0.0-rc.
|
54
|
-
git push origin :refs/tags/v1.0.0-rc.
|
124
|
+
git tag -d v1.0.0-rc.2
|
125
|
+
git push origin :refs/tags/v1.0.0-rc.2
|
55
126
|
|
56
127
|
===PUBLISHING
|
57
128
|
|
58
129
|
Here are the commands used to publish:
|
59
130
|
|
60
|
-
gem push pkg/nuodb-1.0.0.rc.
|
131
|
+
gem push pkg/nuodb-1.0.0.rc.2.gem
|
61
132
|
|
62
133
|
== INSPECTING THE GEM
|
63
134
|
|
64
135
|
It is often useful to inspect the contents of a Gem before distribution.
|
65
136
|
To do this you dump the contents of a gem thus:
|
66
137
|
|
67
|
-
gem unpack pkg/activerecord-nuodb-adapter-1.0.0.rc.
|
138
|
+
gem unpack pkg/activerecord-nuodb-adapter-1.0.0.rc.2.gem
|
139
|
+
|
140
|
+
== RUNNING ACTIVE RECORD COMPLIANCE TEST SUITES
|
141
|
+
|
142
|
+
Install both the NuoDB Ruby Gem and the NuoDB ActiveRecord Adapter Gem:
|
143
|
+
|
144
|
+
gem install nuodb
|
145
|
+
gem install activerecord-nuodb-adapter
|
146
|
+
|
147
|
+
You may need to uninstall an earlier version to ensure you only have
|
148
|
+
the version you want to install:
|
149
|
+
|
150
|
+
gem uninstall activerecord-nuodb-adapter
|
151
|
+
|
152
|
+
Run equivalent commands to the following to set up your environment:
|
153
|
+
|
154
|
+
export NUODB_AR=1
|
155
|
+
export NUODB_ROOT=/Users/rbuck/tmp/nuodb
|
156
|
+
export PATH=${NUODB_ROOT}/bin:${PATH}
|
157
|
+
|
158
|
+
Start up NuoDB as follows:
|
159
|
+
|
160
|
+
java -jar ${NUODB_ROOT}/jar/nuoagent.jar --broker &
|
161
|
+
${NUODB_ROOT}/bin/nuodb --chorus arunit --password bar --dba-user dba --dba-password baz --force &
|
162
|
+
|
163
|
+
Configure your RVM environment:
|
164
|
+
|
165
|
+
cd rails
|
166
|
+
bundle install
|
167
|
+
|
168
|
+
Run the test suite as follows:
|
169
|
+
|
170
|
+
cd activerecord
|
171
|
+
ARCONN=nuodb ruby -Itest test/cases/base_test.rb
|
68
172
|
|
69
|
-
== REFERENCES
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.add_dependency('activerecord', '~> 3.2.8')
|
18
18
|
gem.add_development_dependency('rake', '~> 0.9')
|
19
19
|
gem.add_development_dependency('rdoc', '~> 3.10')
|
20
|
-
gem.add_dependency('nuodb', '~> 1.0.0.rc.
|
20
|
+
gem.add_dependency('nuodb', '~> 1.0.0.rc.2')
|
21
21
|
|
22
22
|
gem.files = `git ls-files`.split($\)
|
23
23
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -30,6 +30,7 @@ require 'arel/visitors/nuodb'
|
|
30
30
|
require 'active_record'
|
31
31
|
require 'active_record/base'
|
32
32
|
require 'active_record/connection_adapters/abstract_adapter'
|
33
|
+
require 'active_record/connection_adapters/abstract/database_statements'
|
33
34
|
require 'active_record/connection_adapters/statement_pool'
|
34
35
|
require 'active_record/connection_adapters/nuodb/version'
|
35
36
|
require 'arel/visitors/bind_visitor'
|
@@ -48,6 +49,7 @@ module ActiveRecord
|
|
48
49
|
end
|
49
50
|
# supply configuration defaults
|
50
51
|
config.reverse_merge! :host => 'localhost'
|
52
|
+
config.reverse_merge! :timezone => 'UTC'
|
51
53
|
ConnectionAdapters::NuoDBAdapter.new nil, logger, nil, config
|
52
54
|
end
|
53
55
|
|
@@ -142,22 +144,8 @@ module ActiveRecord
|
|
142
144
|
|
143
145
|
def simplified_type(field_type)
|
144
146
|
case field_type
|
145
|
-
when /real/i then
|
146
|
-
:float
|
147
|
-
when /money/i then
|
148
|
-
:decimal
|
149
|
-
when /image/i then
|
150
|
-
:binary
|
151
147
|
when /bit/i then
|
152
148
|
:boolean
|
153
|
-
when /uniqueidentifier/i then
|
154
|
-
:string
|
155
|
-
when /datetime/i then
|
156
|
-
:datetime
|
157
|
-
when /varchar\(max\)/ then
|
158
|
-
:text
|
159
|
-
when /timestamp/ then
|
160
|
-
:binary
|
161
149
|
else
|
162
150
|
super
|
163
151
|
end
|
@@ -218,7 +206,8 @@ module ActiveRecord
|
|
218
206
|
end
|
219
207
|
|
220
208
|
def dealloc(stmt)
|
221
|
-
|
209
|
+
# todo
|
210
|
+
#stmt.finish if connection.ping
|
222
211
|
end
|
223
212
|
end
|
224
213
|
|
@@ -300,10 +289,7 @@ module ActiveRecord
|
|
300
289
|
end
|
301
290
|
|
302
291
|
def connect!
|
303
|
-
|
304
|
-
@connection = ::NuoDB::Connection.createSqlConnection(
|
305
|
-
"#{config[:database]}@#{config[:host]}", config[:schema],
|
306
|
-
config[:username], config[:password])
|
292
|
+
@connection = ::NuoDB::Connection.new(config)
|
307
293
|
@statements = StatementPool.new(@connection, @config.fetch(:statement_limit) { 1000 })
|
308
294
|
@quoted_column_names, @quoted_table_names = {}, {}
|
309
295
|
end
|
@@ -320,7 +306,6 @@ module ActiveRecord
|
|
320
306
|
|
321
307
|
def clear_cache!
|
322
308
|
@statements.clear
|
323
|
-
@statements = nil
|
324
309
|
end
|
325
310
|
|
326
311
|
# SAVEPOINT SUPPORT ======================================
|
@@ -364,6 +349,8 @@ module ActiveRecord
|
|
364
349
|
LostConnection.new(message, exception)
|
365
350
|
when *connection_not_established_messages
|
366
351
|
ConnectionNotEstablished.new(message)
|
352
|
+
#when /violates foreign key constraint/
|
353
|
+
# InvalidForeignKey.new(message, exception)
|
367
354
|
else
|
368
355
|
super
|
369
356
|
end
|
@@ -384,7 +371,7 @@ module ActiveRecord
|
|
384
371
|
indexfields.schema = ? AND
|
385
372
|
indexfields.tablename = ?
|
386
373
|
eosql
|
387
|
-
row && row.first
|
374
|
+
row && row.first.downcase
|
388
375
|
end
|
389
376
|
|
390
377
|
def version
|
@@ -395,6 +382,24 @@ module ActiveRecord
|
|
395
382
|
|
396
383
|
public
|
397
384
|
|
385
|
+
# Bug: (4) methods, see: http://tools/jira/browse/DB-2389
|
386
|
+
|
387
|
+
def change_column(table_name, column_name, type, options = {})
|
388
|
+
raise NotImplementedError, "change_column is not implemented"
|
389
|
+
end
|
390
|
+
|
391
|
+
def change_column_default(table_name, column_name, default)
|
392
|
+
raise NotImplementedError, "change_column_default is not implemented"
|
393
|
+
end
|
394
|
+
|
395
|
+
def rename_column(table_name, column_name, new_column_name)
|
396
|
+
raise NotImplementedError, "rename_column is not implemented"
|
397
|
+
end
|
398
|
+
|
399
|
+
def rename_table(table_name, new_name)
|
400
|
+
raise NotImplementedError, "rename_table is not implemented"
|
401
|
+
end
|
402
|
+
|
398
403
|
def table_exists?(table_name)
|
399
404
|
return false unless table_name
|
400
405
|
|
@@ -473,38 +478,63 @@ module ActiveRecord
|
|
473
478
|
end
|
474
479
|
|
475
480
|
def columns(table_name, name = nil)
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
481
|
+
|
482
|
+
# the following query returns something like this:
|
483
|
+
#
|
484
|
+
# INDEXNAME TABLENAME NON_UNIQUE FIELD LENGTH
|
485
|
+
# ---------------------- --------- ---------- --------- ------
|
486
|
+
# COMPANIES..PRIMARY_KEY COMPANIES 0 ID 4
|
487
|
+
# COMPANY_INDEX COMPANIES 1 FIRM_ID 4
|
488
|
+
# COMPANY_INDEX COMPANIES 1 TYPE 255
|
489
|
+
# COMPANY_INDEX COMPANIES 1 RATING 4
|
490
|
+
# COMPANY_INDEX COMPANIES 1 RUBY_TYPE 255
|
491
|
+
|
492
|
+
result = exec_query(<<-eosql, 'SCHEMA', [config[:schema], table_name.to_s])
|
493
|
+
SELECT
|
494
|
+
fields.field as name,
|
495
|
+
fields.defaultvalue as default_value,
|
496
|
+
datatypes.name as data_type,
|
497
|
+
fields.flags as flags
|
498
|
+
FROM
|
499
|
+
system.fields AS fields, system.datatypes AS datatypes
|
500
|
+
WHERE
|
501
|
+
schema = ? AND tablename = ? AND
|
502
|
+
datatypes.id = fields.datatype
|
503
|
+
ORDER BY fields.fieldposition
|
504
|
+
eosql
|
505
|
+
|
506
|
+
columns = []
|
507
|
+
result.map do |row|
|
508
|
+
row.symbolize_keys!
|
509
|
+
columns << NuoDBColumn.new(row[:name].downcase, row[:default_value], row[:data_type], row[:flags].to_i & 1 == 0)
|
495
510
|
end
|
496
|
-
|
511
|
+
columns
|
497
512
|
end
|
498
513
|
|
499
|
-
# todo implement the remaining schema statements methods: rename columns, tables, etc...
|
500
|
-
# todo, and these methods have to clear the cache!!!
|
501
|
-
|
502
514
|
public
|
503
515
|
|
504
516
|
def native_database_types
|
505
|
-
|
517
|
+
{
|
518
|
+
# generic rails types...
|
519
|
+
:binary => {:name => 'binary'},
|
520
|
+
:boolean => {:name => 'boolean'},
|
521
|
+
:date => {:name => 'date'},
|
522
|
+
:datetime => {:name => 'datetime'},
|
523
|
+
:decimal => {:name => 'decimal'},
|
524
|
+
:float => {:name => 'float', :limit => 8},
|
525
|
+
:integer => {:name => 'integer'},
|
526
|
+
:primary_key => 'int not null generated by default as identity primary key',
|
527
|
+
:string => {:name => 'varchar', :limit => 255},
|
528
|
+
:text => {:name => 'varchar', :limit => 255},
|
529
|
+
:time => {:name => 'time'},
|
530
|
+
:timestamp => {:name => 'timestamp'},
|
531
|
+
# nuodb specific types...
|
532
|
+
:char => {:name => 'char'},
|
533
|
+
:numeric => {:name => 'numeric(20)'},
|
534
|
+
}
|
506
535
|
end
|
507
536
|
|
537
|
+
# maps logical rails types to nuodb-specific data types.
|
508
538
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
509
539
|
case type.to_s
|
510
540
|
when 'integer'
|
@@ -526,33 +556,11 @@ module ActiveRecord
|
|
526
556
|
|
527
557
|
private
|
528
558
|
|
529
|
-
NATIVE_DATABASE_TYPES = {
|
530
|
-
:primary_key => 'int not null generated by default as identity primary key',
|
531
|
-
:string => {:name => 'varchar', :limit => 255},
|
532
|
-
:text => {:name => 'varchar', :limit => 255},
|
533
|
-
:integer => {:name => 'integer'},
|
534
|
-
:float => {:name => 'float', :limit => 8},
|
535
|
-
:decimal => {:name => 'decimal'},
|
536
|
-
:datetime => {:name => 'datetime'},
|
537
|
-
:timestamp => {:name => 'datetime'},
|
538
|
-
:time => {:name => 'time'},
|
539
|
-
:date => {:name => 'date'},
|
540
|
-
:binary => {:name => 'binary'},
|
541
|
-
:boolean => {:name => 'boolean'},
|
542
|
-
:char => {:name => 'char'},
|
543
|
-
:varchar_max => {:name => 'varchar(max)'},
|
544
|
-
:nchar => {:name => 'nchar'},
|
545
|
-
:nvarchar => {:name => 'nvarchar', :limit => 255},
|
546
|
-
:nvarchar_max => {:name => 'nvarchar(max)'},
|
547
|
-
:ntext => {:name => 'ntext', :limit => 255},
|
548
|
-
:ss_timestamp => {:name => 'timestamp'}
|
549
|
-
}
|
550
|
-
|
551
559
|
def split_table_name(table)
|
552
560
|
name_parts = table.split '.'
|
553
561
|
case name_parts.length
|
554
562
|
when 1
|
555
|
-
schema_name =
|
563
|
+
schema_name = config[:schema]
|
556
564
|
table_name = name_parts[0]
|
557
565
|
when 2
|
558
566
|
schema_name = name_parts[0]
|
@@ -575,6 +583,11 @@ module ActiveRecord
|
|
575
583
|
@quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`')
|
576
584
|
end
|
577
585
|
|
586
|
+
def type_cast(value, column)
|
587
|
+
return super unless value == true || value == false
|
588
|
+
value ? true : false
|
589
|
+
end
|
590
|
+
|
578
591
|
def quoted_true
|
579
592
|
"'true'"
|
580
593
|
end
|
@@ -583,12 +596,22 @@ module ActiveRecord
|
|
583
596
|
"'false'"
|
584
597
|
end
|
585
598
|
|
599
|
+
def quoted_date(value)
|
600
|
+
if value.acts_like?(:time)
|
601
|
+
zone_conversion_method = :getutc
|
602
|
+
if value.respond_to?(zone_conversion_method)
|
603
|
+
value = value.send(zone_conversion_method)
|
604
|
+
end
|
605
|
+
end
|
606
|
+
value.to_s(:db)
|
607
|
+
end
|
608
|
+
|
586
609
|
# DATABASE STATEMENTS ####################################
|
587
610
|
|
588
611
|
public
|
589
612
|
|
590
613
|
def outside_transaction?
|
591
|
-
|
614
|
+
nil
|
592
615
|
end
|
593
616
|
|
594
617
|
def supports_statement_cache?
|
@@ -619,86 +642,89 @@ module ActiveRecord
|
|
619
642
|
}
|
620
643
|
end
|
621
644
|
|
645
|
+
def default_sequence_name(table, column)
|
646
|
+
result = exec_query(<<-eosql, 'SCHEMA')
|
647
|
+
SELECT generator_sequence FROM system.fields WHERE tablename='#{table}' AND field='#{column}'
|
648
|
+
eosql
|
649
|
+
result.rows.first.first
|
650
|
+
rescue ActiveRecord::StatementInvalid
|
651
|
+
"#{table}$#{column}"
|
652
|
+
end
|
653
|
+
|
622
654
|
def execute(sql, name = 'SQL')
|
623
655
|
log(sql, name) do
|
624
656
|
cache = statements[process_id] ||= {
|
625
|
-
:stmt => raw_connection.
|
657
|
+
:stmt => raw_connection.statement
|
626
658
|
}
|
627
659
|
stmt = cache[:stmt]
|
628
660
|
stmt.execute(sql)
|
629
661
|
end
|
630
662
|
end
|
631
663
|
|
632
|
-
def
|
664
|
+
def exec_insert(sql, name, binds)
|
665
|
+
exec_query sql, name, binds.map { |col, val| type_cast(val, col) }, true
|
666
|
+
end
|
667
|
+
|
668
|
+
def exec_update(sql, name, binds)
|
669
|
+
exec_query(sql, name, binds, true)
|
670
|
+
end
|
671
|
+
|
672
|
+
def exec_delete(sql, name, binds)
|
673
|
+
exec_query(sql, name, binds.map { |col, val| type_cast(val, col) })
|
674
|
+
end
|
675
|
+
|
676
|
+
def exec_query(sql, name = 'SQL', binds = [], get_generated_keys = false)
|
633
677
|
log(sql, name, binds) do
|
634
678
|
if binds.empty?
|
635
679
|
|
636
680
|
cache = statements[process_id] ||= {
|
637
|
-
:stmt => raw_connection.
|
681
|
+
:stmt => raw_connection.statement
|
638
682
|
}
|
639
683
|
stmt = cache[:stmt]
|
640
684
|
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
685
|
+
results = nil
|
686
|
+
if stmt.execute(sql)
|
687
|
+
results = convert_results stmt.results
|
688
|
+
end
|
689
|
+
if get_generated_keys
|
690
|
+
generated_keys_result = stmt.generated_keys
|
691
|
+
if generated_keys_result.nil? || generated_keys_result.rows.empty?
|
692
|
+
@last_inserted_id = nil
|
693
|
+
else
|
694
|
+
@last_inserted_id = generated_keys_result.rows.last[0]
|
695
|
+
end
|
652
696
|
end
|
653
697
|
|
698
|
+
results
|
654
699
|
else
|
655
|
-
|
656
700
|
cache = statements[sql] ||= {
|
657
701
|
:stmt => raw_connection.prepare(sql)
|
658
702
|
}
|
659
703
|
stmt = cache[:stmt]
|
660
|
-
binds.to_enum.with_index(1).each { |bind, column|
|
661
|
-
value = bind[1]
|
662
|
-
case value
|
663
|
-
when String
|
664
|
-
stmt.setString column, value
|
665
|
-
when Integer
|
666
|
-
stmt.setInteger column, value
|
667
|
-
when Fixnum
|
668
|
-
stmt.setInteger column, value
|
669
|
-
when Float
|
670
|
-
stmt.setDouble column, value
|
671
|
-
when TrueClass
|
672
|
-
stmt.setBoolean column, true
|
673
|
-
when FalseClass
|
674
|
-
stmt.setBoolean column, false
|
675
|
-
when Time
|
676
|
-
stmt.setTime column, value
|
677
|
-
else
|
678
|
-
raise "don't know how to bind #{value.class} to parameter #{column}"
|
679
|
-
end
|
680
|
-
}
|
681
704
|
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
else
|
695
|
-
nil
|
705
|
+
results = nil
|
706
|
+
stmt.bind_params binds
|
707
|
+
if stmt.execute
|
708
|
+
results = convert_results stmt.results
|
709
|
+
end
|
710
|
+
if get_generated_keys
|
711
|
+
generated_keys_result = stmt.generated_keys
|
712
|
+
if generated_keys_result.nil? || generated_keys_result.rows.empty?
|
713
|
+
@last_inserted_id = nil
|
714
|
+
else
|
715
|
+
@last_inserted_id = generated_keys_result.rows.last[0]
|
716
|
+
end
|
696
717
|
end
|
697
718
|
|
719
|
+
results
|
698
720
|
end
|
699
721
|
end
|
700
722
|
end
|
701
723
|
|
724
|
+
def convert_results(results)
|
725
|
+
ActiveRecord::Result.new(column_names(results), results.rows)
|
726
|
+
end
|
727
|
+
|
702
728
|
def last_inserted_id(result)
|
703
729
|
@last_inserted_id
|
704
730
|
end
|
@@ -706,68 +732,21 @@ module ActiveRecord
|
|
706
732
|
protected
|
707
733
|
|
708
734
|
def select(sql, name = nil, binds = [])
|
709
|
-
exec_query(sql, name, binds).to_a
|
735
|
+
exec_query(sql, name, binds.map { |col, val| type_cast(val, col) }).to_a
|
710
736
|
end
|
711
737
|
|
712
738
|
protected
|
713
739
|
|
714
740
|
def select_rows(sql, name = nil)
|
715
|
-
|
741
|
+
exec_query(sql, name).rows
|
716
742
|
end
|
717
743
|
|
718
744
|
private
|
719
745
|
|
720
746
|
def column_names (result)
|
721
747
|
return [] if result.nil?
|
722
|
-
|
723
|
-
|
724
|
-
count = meta.getColumnCount
|
725
|
-
(1..count).each { |i|
|
726
|
-
names << meta.getColumnName(i).downcase
|
727
|
-
}
|
728
|
-
names
|
729
|
-
end
|
730
|
-
|
731
|
-
def all_rows(result)
|
732
|
-
rows = []
|
733
|
-
while (row = next_row(result)) != nil
|
734
|
-
rows << row
|
735
|
-
end
|
736
|
-
rows
|
737
|
-
end
|
738
|
-
|
739
|
-
def next_row(result)
|
740
|
-
return nil if result.nil?
|
741
|
-
if result.next
|
742
|
-
meta = result.getMetaData
|
743
|
-
count = meta.getColumnCount
|
744
|
-
row = []
|
745
|
-
(1..count).each { |i|
|
746
|
-
type = meta.getType(i)
|
747
|
-
case type
|
748
|
-
when :SQL_INTEGER
|
749
|
-
row << result.getInteger(i)
|
750
|
-
when :SQL_DOUBLE
|
751
|
-
row << result.getDouble(i)
|
752
|
-
when :SQL_STRING
|
753
|
-
row << result.getString(i)
|
754
|
-
when :SQL_DATE
|
755
|
-
row << result.getDate(i)
|
756
|
-
when :SQL_TIME
|
757
|
-
row << result.getTime(i)
|
758
|
-
when :SQL_TIMESTAMP
|
759
|
-
row << result.getTimestamp(i)
|
760
|
-
when :SQL_CHAR
|
761
|
-
row << result.getChar(i)
|
762
|
-
when :SQL_BOOLEAN
|
763
|
-
row << result.getBoolean(i)
|
764
|
-
else
|
765
|
-
raise "unknown type #{type} for column #{i}"
|
766
|
-
end
|
767
|
-
}
|
768
|
-
row
|
769
|
-
else
|
770
|
-
nil
|
748
|
+
result.columns.inject([]) do |array, column|
|
749
|
+
array << column.name.downcase
|
771
750
|
end
|
772
751
|
end
|
773
752
|
|
data/test/test_simple.rb
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
|
29
29
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
|
30
30
|
|
31
|
-
require
|
31
|
+
require 'test/unit'
|
32
32
|
require 'rubygems'
|
33
33
|
require 'active_record'
|
34
34
|
|
@@ -37,7 +37,7 @@ class User < ActiveRecord::Base
|
|
37
37
|
|
38
38
|
def to_s
|
39
39
|
return "User(#{@id}), Username: #{@user_name}, Name: #{@first_name} #{@last_name}, #{@admin ? "admin" : "member"}\n" +
|
40
|
-
|
40
|
+
" Address: #{@addr}\n"
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -45,7 +45,7 @@ class Addr < ActiveRecord::Base
|
|
45
45
|
belongs_to :User
|
46
46
|
|
47
47
|
def to_s
|
48
|
-
|
48
|
+
"Addr(#{@id}:#{@user_id}) Street: #{@street} City: #{@city} Zip: #{@zip}"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -54,12 +54,12 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
54
54
|
def setup()
|
55
55
|
|
56
56
|
ActiveRecord::Base.establish_connection(
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
:adapter => 'nuodb',
|
58
|
+
:database => 'test',
|
59
|
+
:schema => 'test',
|
60
|
+
:username => 'cloud',
|
61
|
+
:password => 'user'
|
62
|
+
)
|
63
63
|
|
64
64
|
ActiveRecord::Schema.drop_table(User.table_name) rescue nil
|
65
65
|
|
@@ -72,6 +72,7 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
72
72
|
t.string :email, :limit => 20
|
73
73
|
t.string :user_name, :limit => 20
|
74
74
|
t.boolean :admin
|
75
|
+
t.time :created
|
75
76
|
end
|
76
77
|
create_table Addr.table_name do |t|
|
77
78
|
t.integer :user_id
|
@@ -83,7 +84,6 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
83
84
|
|
84
85
|
end
|
85
86
|
|
86
|
-
|
87
87
|
def test_create_user_records
|
88
88
|
|
89
89
|
fred = User.create do |u|
|
@@ -92,10 +92,12 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
92
92
|
u.email = "fredf@example.com"
|
93
93
|
u.user_name = "fred"
|
94
94
|
u.admin = true
|
95
|
+
u.created = Time.utc(2000, 1, 1, 10, 35, 50)
|
95
96
|
end
|
96
97
|
|
97
98
|
assert_not_nil fred
|
98
99
|
assert_not_nil fred.id
|
100
|
+
assert_equal Time.utc(2000, 1, 1, 10, 35, 50), fred.created
|
99
101
|
|
100
102
|
fred.create_addr do |a|
|
101
103
|
a.street = "301 Cobblestone Way"
|
@@ -130,21 +132,21 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
130
132
|
|
131
133
|
mask = 0
|
132
134
|
User.find do |entry|
|
133
|
-
case entry.id
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
case entry.id
|
136
|
+
when fred.id
|
137
|
+
assert_equal 'Fred', entry.first_name
|
138
|
+
assert_equal 'Flintstone', entry.last_name
|
139
|
+
assert_equal '301 Cobblestone Way', entry.addr.street
|
140
|
+
mask += 1
|
141
|
+
nil
|
142
|
+
when barney.id
|
143
|
+
assert_equal 'Barney', entry.first_name
|
144
|
+
assert_equal 'Rubble', entry.last_name
|
145
|
+
assert_equal '303 Cobblestone Way', entry.addr.street
|
146
|
+
mask += 10
|
147
|
+
nil
|
148
|
+
else
|
149
|
+
raise "unknown entry.id: #{entry.id}"
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
@@ -155,27 +157,38 @@ class NuoSimpleTest < Test::Unit::TestCase
|
|
155
157
|
entry.last_name = entry.last_name.upcase
|
156
158
|
# TODO entry.admin = !entry.admin
|
157
159
|
entry.addr.street = entry.addr.street.upcase
|
158
|
-
entry.addr.save
|
160
|
+
entry.addr.save
|
159
161
|
entry.save
|
160
162
|
end
|
161
163
|
|
162
164
|
assert_equal 2, User.count
|
163
165
|
|
164
166
|
User.find do |entry|
|
165
|
-
case entry.id
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
167
|
+
case entry.id
|
168
|
+
when fred.id
|
169
|
+
assert_equal 'FRED', entry.first_name
|
170
|
+
assert_equal '301 COBBLESTONE WAY', entry.addr.street
|
171
|
+
nil
|
172
|
+
when barney.id
|
173
|
+
assert_equal 'BARNEY', entry.first_name
|
174
|
+
assert_equal '303 COBBLESTONE WAY', entry.addr.street
|
175
|
+
nil
|
176
|
+
else
|
177
|
+
raise 'unknown entry.id'
|
176
178
|
end
|
177
179
|
end
|
178
180
|
|
181
|
+
User.default_timezone = :utc
|
182
|
+
attributes = {"created(1i)" => "2000",
|
183
|
+
"created(2i)" => "1",
|
184
|
+
"created(3i)" => "1",
|
185
|
+
"created(4i)" => "10",
|
186
|
+
"created(5i)" => "35",
|
187
|
+
"created(6i)" => "50"}
|
188
|
+
user = User.new(attributes)
|
189
|
+
assert_equal Time.utc(2000, 1, 1, 10, 35, 50), user.created
|
190
|
+
User.default_timezone = :local
|
191
|
+
|
179
192
|
end
|
180
193
|
|
181
194
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-nuodb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.rc.
|
4
|
+
version: 1.0.0.rc.2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.0.0.rc.
|
69
|
+
version: 1.0.0.rc.2
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.0.0.rc.
|
77
|
+
version: 1.0.0.rc.2
|
78
78
|
description: An adapter for ActiveRecord and AREL to support the NuoDB distributed
|
79
79
|
database backend.
|
80
80
|
email:
|
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
122
|
version: 1.3.1
|
123
123
|
requirements: []
|
124
124
|
rubyforge_project:
|
125
|
-
rubygems_version: 1.8.
|
125
|
+
rubygems_version: 1.8.23
|
126
126
|
signing_key:
|
127
127
|
specification_version: 3
|
128
128
|
summary: ActiveRecord adapter with AREL support for NuoDB.
|