rubyfb 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -1
- data/Manifest +5 -1
- data/Rakefile +4 -3
- data/ext/FireRuby.c +1 -1
- data/ext/ResultSet.c +3 -2
- data/ext/extconf.rb +3 -1
- data/lib/Connection.rb +8 -0
- data/lib/ProcedureCall.rb +65 -0
- data/lib/SQLType.rb +2 -2
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +34 -19
- data/lib/rubyfb.rb +3 -0
- data/lib/rubyfb_lib.so +0 -0
- data/mswin32fb/fbclient_ms.lib +0 -0
- data/mswin32fb/ibase.h +2555 -0
- data/mswin32fb/iberror.h +1741 -0
- data/rubyfb.gemspec +4 -4
- metadata +10 -4
- data/ext/mkmf.bat +0 -1
data/CHANGELOG
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
+
v0.5.3 ==
|
2
|
+
rename top module to Rubyfb
|
3
|
+
!!!WARNING!!!
|
4
|
+
this change breaks the "drop in" compatibility with FireRuby if FireRuby module name
|
5
|
+
was explicitly used. Simple search and replace should do the work
|
6
|
+
|
7
|
+
RubyfbAdapter - add support for :sql_role_name connection option
|
8
|
+
Add new class ProcedureCall - representing firebird stored procedure
|
9
|
+
Add prepare_call() function to the Rubyfb::Connection class - returning ProcedureCall object
|
10
|
+
Add execute_procedure(procedure_name, parameter_values) function to the RubyfbAdapter class
|
11
|
+
Windows build fixes
|
12
|
+
|
1
13
|
v0.5.2 ==
|
2
14
|
Use Echoe as build system
|
3
15
|
By default release as "source only" gem
|
4
|
-
Add binary build
|
16
|
+
Add binary build rake task - binpkg
|
5
17
|
|
6
18
|
v0.5.1 initial version
|
data/Manifest
CHANGED
@@ -43,13 +43,17 @@ ext/Transaction.h
|
|
43
43
|
ext/TypeMap.c
|
44
44
|
ext/TypeMap.h
|
45
45
|
ext/extconf.rb
|
46
|
-
|
46
|
+
lib/Connection.rb
|
47
|
+
lib/ProcedureCall.rb
|
47
48
|
lib/SQLType.rb
|
48
49
|
lib/active_record/connection_adapters/rubyfb_adapter.rb
|
49
50
|
lib/mkdoc
|
50
51
|
lib/rubyfb.rb
|
51
52
|
lib/rubyfb_lib.so
|
52
53
|
lib/src.rb
|
54
|
+
mswin32fb/fbclient_ms.lib
|
55
|
+
mswin32fb/ibase.h
|
56
|
+
mswin32fb/iberror.h
|
53
57
|
test/AddRemoveUserTest.rb
|
54
58
|
test/BackupRestoreTest.rb
|
55
59
|
test/BlobTest.rb
|
data/Rakefile
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'echoe'
|
2
|
-
e = Echoe.new('rubyfb', '0.5.
|
2
|
+
e = Echoe.new('rubyfb', '0.5.3') do |p|
|
3
3
|
p.description = "Firebird SQL access library"
|
4
4
|
p.url = "http://rubyforge.org/projects/rubyfb"
|
5
5
|
p.author = "George Georgiev"
|
6
6
|
p.email = "georgiev@heatbs.com"
|
7
7
|
p.rdoc_pattern = ["{examples,ext,lib}/*.rb", "CHANGELOG", "README", "LICENSE"]
|
8
|
+
p.need_tar_gz = !PLATFORM.include?("win32")
|
8
9
|
|
9
|
-
|
10
|
+
if ARGV.include? "binpkg"
|
10
11
|
p.platform=Gem::Platform::CURRENT
|
11
12
|
p.eval = Proc.new {
|
12
13
|
self.extensions=nil
|
@@ -15,6 +16,6 @@ e = Echoe.new('rubyfb', '0.5.2') do |p|
|
|
15
16
|
end
|
16
17
|
end
|
17
18
|
e.clean_pattern = e.clean_pattern - e.clean_pattern.grep(/^lib/)
|
19
|
+
e.clean_pattern = e.clean_pattern - e.clean_pattern.grep(/^mswin32fb/)
|
18
20
|
|
19
21
|
task :binpkg => [:compile, :repackage]
|
20
|
-
task :binrelease => [:compile, :release]
|
data/ext/FireRuby.c
CHANGED
data/ext/ResultSet.c
CHANGED
@@ -262,6 +262,7 @@ VALUE fetchResultSetEntry(VALUE self)
|
|
262
262
|
Data_Get_Struct(self, ResultsHandle, results);
|
263
263
|
if(results->handle != 0)
|
264
264
|
{
|
265
|
+
VALUE array,number;
|
265
266
|
value = results->procedure_output_fetch_state;
|
266
267
|
if(value < 0) {
|
267
268
|
value = isc_dsql_fetch(status, &results->handle, results->dialect,
|
@@ -270,8 +271,8 @@ VALUE fetchResultSetEntry(VALUE self)
|
|
270
271
|
/* move procedure_output_fetch_state ahead - fetch only one row */
|
271
272
|
results->procedure_output_fetch_state = 100;
|
272
273
|
}
|
273
|
-
|
274
|
-
|
274
|
+
array = Qnil;
|
275
|
+
number = Qnil;
|
275
276
|
switch(value)
|
276
277
|
{
|
277
278
|
case 0 :
|
data/ext/extconf.rb
CHANGED
@@ -12,10 +12,12 @@ if PLATFORM.include?("darwin")
|
|
12
12
|
firebird_lib="/Library/Frameworks/Firebird.framework/Libraries"
|
13
13
|
elsif PLATFORM.include?("win32")
|
14
14
|
$LDFLAGS = $LDFLAGS + " fbclient_ms.lib"
|
15
|
-
$CFLAGS = $CFLAGS + " -DOS_WIN32"
|
15
|
+
$CFLAGS = "-MT #{$CFLAGS}".gsub!(/-MD\s*/, '') + " -DOS_WIN32"
|
16
16
|
dir_config("win32")
|
17
17
|
dir_config("winsdk")
|
18
18
|
dir_config("dotnet")
|
19
|
+
firebird_include="../mswin32fb"
|
20
|
+
firebird_lib="../mswin32fb"
|
19
21
|
elsif PLATFORM.include?("linux")
|
20
22
|
$LDFLAGS = $LDFLAGS + " -lfbclient -lpthread"
|
21
23
|
$CFLAGS = $CFLAGS + " -DOS_UNIX"
|
data/lib/Connection.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Rubyfb
|
2
|
+
class ProcedureCall
|
3
|
+
attr_reader :connection, :procedure_name, :param_names
|
4
|
+
|
5
|
+
def initialize(connection, procedure_name)
|
6
|
+
@procedure_name=procedure_name
|
7
|
+
@connection=connection
|
8
|
+
@param_names = []
|
9
|
+
connection.execute_immediate(
|
10
|
+
"SELECT RDB$PARAMETER_NAME
|
11
|
+
FROM RDB$PROCEDURE_PARAMETERS
|
12
|
+
WHERE RDB$PROCEDURE_NAME='#{procedure_name}' and RDB$PARAMETER_TYPE = 0
|
13
|
+
ORDER BY RDB$PARAMETER_NUMBER"
|
14
|
+
) do |row|
|
15
|
+
row.each do |col, val|
|
16
|
+
@param_names << column_key(val)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# execute stored procedure vith parameter values bound to values
|
22
|
+
# passing NULL for all parameters not found in values
|
23
|
+
# returns output parameters as a hash - { :output_parameter_name=>value, ... }
|
24
|
+
def execute(values={}, transaction=nil)
|
25
|
+
result = {}
|
26
|
+
execute_statement(values, transaction) do |row|
|
27
|
+
row.each do |col, value|
|
28
|
+
result[column_key(col)] = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
return result
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns string containing coma separated parameter values
|
35
|
+
# corresponding to param_names array, quoted/formated in SQL format
|
36
|
+
def sql_value_list(values)
|
37
|
+
param_names.collect{|p| quote_value(values[p])}.join(',')
|
38
|
+
end
|
39
|
+
|
40
|
+
def quote_value(value)
|
41
|
+
# TODO - proper quoting
|
42
|
+
value ? "'#{value}'" : "NULL"
|
43
|
+
end
|
44
|
+
private
|
45
|
+
def bind_params(values)
|
46
|
+
"(#{sql_value_list(values)})" unless param_names.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def gen_sql(values)
|
50
|
+
"execute procedure #{procedure_name}#{bind_params(values)};"
|
51
|
+
end
|
52
|
+
|
53
|
+
def execute_statement(values={}, transaction=nil, &block)
|
54
|
+
if transaction
|
55
|
+
connection.execute(gen_sql(values), transaction, &block)
|
56
|
+
else
|
57
|
+
connection.execute_immediate(gen_sql(values), &block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def column_key(column_name)
|
62
|
+
(column_name =~ /[[:lower:]]/ ? column_name : column_name.downcase).strip.intern
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/SQLType.rb
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
# The Initial Developer of the Original Code is Peter Wood. All Rights
|
19
19
|
# Reserved.
|
20
20
|
|
21
|
-
module
|
21
|
+
module Rubyfb
|
22
22
|
# This class is used to represent SQL table column tables.
|
23
23
|
class SQLType
|
24
24
|
# A definition for a base SQL type.
|
@@ -221,4 +221,4 @@ module FireRuby
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
end # End of the SQLType class.
|
224
|
-
end # End of the FireRuby module.
|
224
|
+
end # End of the FireRuby module.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Author: Ken Kunz <kennethkunz@gmail.com>
|
2
2
|
require 'active_record/connection_adapters/abstract_adapter'
|
3
3
|
|
4
|
-
module
|
4
|
+
module Rubyfb # :nodoc: all
|
5
5
|
NON_EXISTENT_DOMAIN_ERROR = "335544569"
|
6
6
|
class Database
|
7
7
|
def self.db_string_for(config)
|
@@ -18,6 +18,18 @@ module FireRuby # :nodoc: all
|
|
18
18
|
return db
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
class ProcedureCall
|
23
|
+
class SQLParser < ActiveRecord::Base
|
24
|
+
def self.bind_params(sql_array)
|
25
|
+
sanitize_sql_array(sql_array)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def sql_value_list(values)
|
30
|
+
SQLParser.bind_params([param_names.collect{|p| '?'}.join(',')] + param_names.collect{|p| values[p]})
|
31
|
+
end
|
32
|
+
end
|
21
33
|
end
|
22
34
|
|
23
35
|
module ActiveRecord
|
@@ -25,8 +37,11 @@ module ActiveRecord
|
|
25
37
|
def self.rubyfb_connection(config) # :nodoc:
|
26
38
|
require_library_or_gem 'rubyfb'
|
27
39
|
config.symbolize_keys!
|
28
|
-
db =
|
40
|
+
db = Rubyfb::Database.new_from_config(config)
|
29
41
|
connection_params = config.values_at(:username, :password)
|
42
|
+
if config[:sql_role_name]
|
43
|
+
connection_params << {Rubyfb::Connection::SQL_ROLE_NAME=>config[:sql_role_name]}
|
44
|
+
end
|
30
45
|
connection = db.connect(*connection_params)
|
31
46
|
ConnectionAdapters::RubyfbAdapter.new(connection, logger, connection_params)
|
32
47
|
end
|
@@ -46,7 +61,7 @@ module ActiveRecord
|
|
46
61
|
VARCHAR_MAX_LENGTH = 32_765
|
47
62
|
|
48
63
|
def initialize(connection, name, domain, type, sub_type, length, precision, scale, default_source, null_flag)
|
49
|
-
@firebird_type =
|
64
|
+
@firebird_type = Rubyfb::SQLType.to_base_type(type, sub_type).to_s
|
50
65
|
|
51
66
|
super(name.downcase, nil, @firebird_type, !null_flag)
|
52
67
|
|
@@ -118,11 +133,6 @@ module ActiveRecord
|
|
118
133
|
end
|
119
134
|
end
|
120
135
|
|
121
|
-
# The Firebird adapter relies on the FireRuby[http://rubyforge.org/projects/fireruby/]
|
122
|
-
# extension, version 0.4.0 or later (available as a gem or from
|
123
|
-
# RubyForge[http://rubyforge.org/projects/fireruby/]). FireRuby works with
|
124
|
-
# Firebird 1.5.x on Linux, OS X and Win32 platforms.
|
125
|
-
#
|
126
136
|
# == Usage Notes
|
127
137
|
#
|
128
138
|
# === Sequence (Generator) Names
|
@@ -261,6 +271,8 @@ module ActiveRecord
|
|
261
271
|
# <tt>:charset</tt>::
|
262
272
|
# Specifies the character set to be used by the connection. Refer to
|
263
273
|
# Firebird documentation for valid options.
|
274
|
+
# <tt>:sql_role_name</tt>::
|
275
|
+
# Specifies the SQL role name used by the connection.
|
264
276
|
class RubyfbAdapter < AbstractAdapter
|
265
277
|
TEMP_COLUMN_NAME = 'AR$TEMP_COLUMN'
|
266
278
|
|
@@ -374,7 +386,7 @@ module ActiveRecord
|
|
374
386
|
|
375
387
|
def execute(sql, name = nil, &block) # :nodoc:
|
376
388
|
exec_result = execute_statement(sql, name, &block)
|
377
|
-
if exec_result.instance_of?(
|
389
|
+
if exec_result.instance_of?(Rubyfb::ResultSet)
|
378
390
|
exec_result.close
|
379
391
|
exec_result = nil
|
380
392
|
end
|
@@ -409,7 +421,7 @@ module ActiveRecord
|
|
409
421
|
# called directly; used by ActiveRecord to get the next primary key value
|
410
422
|
# when inserting a new database record (see #prefetch_primary_key?).
|
411
423
|
def next_sequence_value(sequence_name)
|
412
|
-
|
424
|
+
Rubyfb::Generator.new(sequence_name, @connection).next(1)
|
413
425
|
end
|
414
426
|
|
415
427
|
# Inserts the given fixture into the table. Overridden to properly handle blobs.
|
@@ -430,7 +442,7 @@ module ActiveRecord
|
|
430
442
|
value = value.to_yaml if col.text? && klass.serialized_attributes[col.name]
|
431
443
|
value = value.read if value.respond_to?(:read)
|
432
444
|
next if value.nil? || (value == '')
|
433
|
-
s =
|
445
|
+
s = Rubyfb::Statement.new(@connection, @transaction, "UPDATE #{table_name} set #{col.name} = ? WHERE #{klass.primary_key} = #{id}", 3)
|
434
446
|
s.execute_for([value.to_s])
|
435
447
|
s.close
|
436
448
|
end
|
@@ -449,7 +461,7 @@ module ActiveRecord
|
|
449
461
|
charset = select_rows(sql).first[0].rstrip
|
450
462
|
disconnect!
|
451
463
|
@connection.database.drop(*@connection_params)
|
452
|
-
|
464
|
+
Rubyfb::Database.create(@connection.database.file,
|
453
465
|
@connection_params[0], @connection_params[1], 4096, charset)
|
454
466
|
end
|
455
467
|
|
@@ -603,6 +615,10 @@ module ActiveRecord
|
|
603
615
|
end
|
604
616
|
end
|
605
617
|
|
618
|
+
def execute_procedure(procedure_name, values={})
|
619
|
+
@connection.prepare_call(procedure_name).execute(values, @transaction)
|
620
|
+
end
|
621
|
+
|
606
622
|
private
|
607
623
|
def execute_statement(sql, name = nil, &block) # :nodoc:
|
608
624
|
@fbe = nil
|
@@ -662,7 +678,7 @@ module ActiveRecord
|
|
662
678
|
row.each do |column, value|
|
663
679
|
fields << fb_to_ar_case(column) if row.number == 1
|
664
680
|
|
665
|
-
if
|
681
|
+
if Rubyfb::Blob === value
|
666
682
|
temp = value.to_s
|
667
683
|
value.close
|
668
684
|
value = temp
|
@@ -746,20 +762,20 @@ module ActiveRecord
|
|
746
762
|
end
|
747
763
|
|
748
764
|
def copy_sequence_value(from, to)
|
749
|
-
sequence_value =
|
765
|
+
sequence_value = Rubyfb::Generator.new(default_sequence_name(from), @connection).last
|
750
766
|
execute_statement("SET GENERATOR #{default_sequence_name(to)} TO #{sequence_value}")
|
751
767
|
end
|
752
768
|
|
753
769
|
def sequence_exists?(sequence_name)
|
754
|
-
|
770
|
+
Rubyfb::Generator.exists?(sequence_name, @connection)
|
755
771
|
end
|
756
772
|
|
757
773
|
def create_sequence(sequence_name)
|
758
|
-
|
774
|
+
Rubyfb::Generator.create(sequence_name.to_s, @connection)
|
759
775
|
end
|
760
776
|
|
761
777
|
def drop_sequence(sequence_name)
|
762
|
-
|
778
|
+
Rubyfb::Generator.new(sequence_name.to_s, @connection).drop
|
763
779
|
end
|
764
780
|
|
765
781
|
def create_boolean_domain
|
@@ -785,7 +801,7 @@ module ActiveRecord
|
|
785
801
|
end
|
786
802
|
|
787
803
|
def non_existent_domain_error?
|
788
|
-
$!.message.include?
|
804
|
+
$!.message.include? Rubyfb::NON_EXISTENT_DOMAIN_ERROR
|
789
805
|
end
|
790
806
|
|
791
807
|
# Maps uppercase Firebird column names to lowercase for ActiveRecord;
|
@@ -802,4 +818,3 @@ module ActiveRecord
|
|
802
818
|
end
|
803
819
|
end
|
804
820
|
end
|
805
|
-
|
data/lib/rubyfb.rb
CHANGED
data/lib/rubyfb_lib.so
CHANGED
Binary file
|
Binary file
|