testability-driver 0.9.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +1 -1
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +11 -7
- data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +8 -0
- data/lib/tdriver/base/behaviour/factory.rb +229 -209
- data/lib/tdriver/base/errors.rb +3 -0
- data/lib/tdriver/base/state_object.rb +11 -20
- data/lib/tdriver/base/sut/controller.rb +4 -4
- data/lib/tdriver/base/sut/factory.rb +205 -170
- data/lib/tdriver/base/sut/generic/behaviours/application.rb +256 -174
- data/lib/tdriver/base/sut/generic/behaviours/find.rb +17 -11
- data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +57 -66
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +578 -497
- data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +41 -15
- data/lib/tdriver/base/sut/generic/behaviours/verification.rb +48 -19
- data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
- data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +25 -13
- data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +16 -10
- data/lib/tdriver/base/sut/generic/plugin.rb +9 -3
- data/lib/tdriver/base/sut/sut.rb +41 -33
- data/lib/tdriver/base/test_object/abstract.rb +26 -3
- data/lib/tdriver/base/test_object/adapter.rb +399 -0
- data/lib/tdriver/base/test_object/behaviours/syncronization.rb +56 -14
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +663 -197
- data/lib/tdriver/base/test_object/cache.rb +132 -0
- data/lib/tdriver/base/test_object/factory.rb +677 -426
- data/lib/tdriver/base/test_object/factory_new.rb +202 -0
- data/lib/tdriver/base/test_object/identificator.rb +24 -17
- data/lib/tdriver/base/test_object/loader.rb +9 -3
- data/lib/tdriver/base/test_object/verification.rb +181 -0
- data/lib/tdriver/loader.rb +1 -1
- data/lib/tdriver/report/report.rb +2 -0
- data/lib/tdriver/report/report_api.rb +4 -4
- data/lib/tdriver/report/report_creator.rb +29 -3
- data/lib/tdriver/report/report_data_presentation.rb +7 -3
- data/lib/tdriver/report/report_execution_statistics.rb +80 -21
- data/lib/tdriver/report/report_javascript.rb +192 -0
- data/lib/tdriver/report/report_test_case_run.rb +22 -0
- data/lib/tdriver/report/report_test_run.rb +62 -55
- data/lib/tdriver/report/report_writer.rb +57 -56
- data/lib/tdriver/tdriver.rb +14 -41
- data/lib/tdriver/util/common/error.rb +1 -0
- data/lib/tdriver/util/common/exceptions.rb +12 -0
- data/lib/tdriver/util/common/file.rb +12 -6
- data/lib/tdriver/util/common/gem.rb +2 -1
- data/lib/tdriver/util/common/hash.rb +152 -0
- data/lib/tdriver/util/common/kernel.rb +49 -34
- data/lib/tdriver/util/common/loader.rb +21 -17
- data/lib/tdriver/util/common/numeric.rb +39 -0
- data/lib/tdriver/util/common/object.rb +115 -0
- data/lib/tdriver/util/common/string.rb +55 -2
- data/lib/tdriver/util/dbaccess/dbaccess.rb +194 -161
- data/lib/tdriver/util/dynamic_attribute_filter.rb +6 -0
- data/lib/tdriver/util/hooking.rb +2 -2
- data/lib/tdriver/util/loader.rb +2 -2
- data/lib/tdriver/util/localisation/localisation.rb +277 -18
- data/lib/tdriver/util/logger.rb +142 -13
- data/lib/tdriver/util/parameter/parameter_hash.rb +8 -5
- data/lib/tdriver/util/parameter/parameter_xml.rb +18 -2
- data/lib/tdriver/util/recorder.rb +17 -12
- data/lib/tdriver/util/user_data/user_data.rb +3 -2
- data/lib/tdriver/util/{video_rec.rb → video_utils.rb} +136 -16
- data/lib/tdriver/util/xml/abstraction.rb +7 -0
- data/lib/tdriver/util/xml/attribute.rb +32 -0
- data/lib/tdriver/util/xml/loader.rb +8 -2
- data/lib/tdriver/util/xml/nil_node.rb +95 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +46 -7
- data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +19 -9
- data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +1 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +13 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +6 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +27 -15
- data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +57 -0
- data/lib/tdriver/util/xml/text.rb +32 -0
- data/lib/tdriver/util/xml/xml.rb +35 -22
- data/lib/tdriver/version.rb +1 -1
- data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +41 -34
- data/lib/tdriver-devtools/doc/generate.rb +31 -6
- data/lib/tdriver-devtools/doc/xslt/template.xsl +46 -25
- data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
- data/lib/tdriver-devtools/tests/feature_tests/update +1 -1
- data/lib/tdriver.rb +0 -3
- data/xml/behaviours/generic.xml +1 -1
- data/xml/defaults/generic.xml +4 -90
- data/xml/templates/generic.xml +33 -25
- metadata +21 -29
- data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +0 -245
- data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +0 -964
- data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +0 -68
- data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +0 -1865
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +0 -4
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +0 -3
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +0 -12
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +0 -5
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +0 -1
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +0 -2
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +0 -7
- data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +0 -14
- data/lib/tdriver-devtools/behaviour/xml_generator/update +0 -3
- data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +0 -233
- data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +0 -194
@@ -20,20 +20,24 @@
|
|
20
20
|
require 'rbconfig' # ??
|
21
21
|
|
22
22
|
# common modules - should be generic and runnable as standalone
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
23
|
+
[
|
24
|
+
# Ruby object extensions
|
25
|
+
'object.rb',
|
26
|
+
'numeric.rb',
|
27
|
+
'hash.rb',
|
28
|
+
'string.rb',
|
29
|
+
|
30
|
+
'exceptions.rb',
|
31
|
+
'error.rb', # TODO: move custom exceptions to exceptions.rb
|
32
|
+
|
33
|
+
'array.rb',
|
34
|
+
'crc16.rb',
|
35
|
+
'environment.rb',
|
36
|
+
'file.rb',
|
37
|
+
'gem.rb',
|
38
|
+
'kernel.rb',
|
39
|
+
'retryable.rb' ].each{ | filename |
|
40
|
+
|
41
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), filename ) )
|
42
|
+
|
43
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of Testability Driver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
# extend Ruby Numeric class functionality
|
21
|
+
class Numeric
|
22
|
+
|
23
|
+
def positive?
|
24
|
+
self > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def non_negative?
|
28
|
+
self >= 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def non_positive?
|
32
|
+
self <= 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def negative?
|
36
|
+
self < 0
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of Testability Driver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
# extend Ruby Object class functionality
|
21
|
+
class Object
|
22
|
+
|
23
|
+
# define method to class instance
|
24
|
+
def meta_def method_name, &block
|
25
|
+
|
26
|
+
( class << self; self; end ).instance_eval{ define_method method_name, &block }
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# Compare receiver object type with given types. Raises exception is class name does not equal.
|
31
|
+
def check_type( types, message = "wrong argument type $1 (expected $2)" )
|
32
|
+
|
33
|
+
# raise exception if message is not type of String
|
34
|
+
raise TypeError.new( "wrong argument type %s for message (expected String)" % [ message.class ] ) unless message.kind_of?( String )
|
35
|
+
|
36
|
+
# create array of types
|
37
|
+
type_array = types.kind_of?( Array ) ? types : [ types ]
|
38
|
+
|
39
|
+
# default result value
|
40
|
+
found = false
|
41
|
+
|
42
|
+
# collect verbose type list
|
43
|
+
verbose_type_list = type_array.each_with_index.collect{ | type, index |
|
44
|
+
|
45
|
+
raise TypeError.new( "invalid argument type #{ type } for check_type. Did you mean #{ type.class }?" ) unless type.kind_of?( Class )
|
46
|
+
|
47
|
+
found = true if self.kind_of?( type )
|
48
|
+
|
49
|
+
# result string, separate types if multiple types given
|
50
|
+
"#{ ( ( index > 0 ) ? ( index + 1 < type_array.count ? ", " : " or " ) : "" ) }#{ type.to_s }"
|
51
|
+
|
52
|
+
}.join
|
53
|
+
|
54
|
+
# raise exception if type did not match
|
55
|
+
unless found
|
56
|
+
|
57
|
+
# convert macros
|
58
|
+
[ self.class, verbose_type_list, self.inspect ].each_with_index{ | param, index | message.gsub!( "$#{ index + 1 }", param.to_s ) }
|
59
|
+
|
60
|
+
# raise the exception
|
61
|
+
raise TypeError.new( message )
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# pass self as return value
|
66
|
+
self
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def not_nil( message = "Value must not be nil", exception = ArgumentError )
|
71
|
+
|
72
|
+
raise exception.new( message ) if self.nil?
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
def validate( values, message = "Unexpected value $3 for $1 (expected $2)" )
|
77
|
+
|
78
|
+
# raise exception if message is not type of String
|
79
|
+
raise TypeError.new( "wrong argument type %s for message (expected String)" % [ message.class ] ) unless message.kind_of?( String )
|
80
|
+
|
81
|
+
# create array of values
|
82
|
+
values_array = values.kind_of?( Array ) ? values : [ values ]
|
83
|
+
|
84
|
+
# default result value
|
85
|
+
found = false
|
86
|
+
|
87
|
+
# collect verbose type list
|
88
|
+
verbose_values_list = values_array.each_with_index.collect{ | value, index |
|
89
|
+
|
90
|
+
raise TypeError.new( "Invalid argument type #{ value.class } for value (expected #{ self.class })" ) unless value.kind_of?( self.class )
|
91
|
+
|
92
|
+
found = true if self == value
|
93
|
+
|
94
|
+
# result string, separate types if multiple types given
|
95
|
+
"#{ ( ( index > 0 ) ? ( index + 1 < values_array.count ? ", " : " or " ) : "" ) }#{ value.inspect }"
|
96
|
+
|
97
|
+
}.join
|
98
|
+
|
99
|
+
# raise exception if value was not found
|
100
|
+
unless found
|
101
|
+
|
102
|
+
# convert macros
|
103
|
+
[ self.class, verbose_values_list, self.inspect ].each_with_index{ | param, index | message.gsub!( "$#{ index + 1 }", param.to_s ) }
|
104
|
+
|
105
|
+
# raise the exception
|
106
|
+
raise ArgumentError.new( message )
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
# pass self as return value
|
111
|
+
self
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -17,6 +17,58 @@
|
|
17
17
|
##
|
18
18
|
############################################################################
|
19
19
|
|
20
|
+
class String
|
21
|
+
|
22
|
+
def not_empty( message = "String must not be empty", exception = ArgumentError )
|
23
|
+
|
24
|
+
raise exception.new( message ) if self.empty?
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
# Function determines if string is "true" or "false"
|
29
|
+
# == params
|
30
|
+
# string:: String
|
31
|
+
# == returns
|
32
|
+
# TrueClass/FalseClass
|
33
|
+
def boolean?
|
34
|
+
|
35
|
+
/^(true|false)$/i.match( self ).kind_of?( MatchData )
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# Function determines if string is numeric
|
40
|
+
# == params
|
41
|
+
# string:: Numeric string
|
42
|
+
# == returns
|
43
|
+
# TrueClass/FalseClass
|
44
|
+
def numeric?
|
45
|
+
|
46
|
+
/^[0-9]+$/.match( self ).kind_of?( MatchData )
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# Function converts "true" or "false" to boolean
|
51
|
+
# == params
|
52
|
+
# string:: String
|
53
|
+
# == returns
|
54
|
+
# TrueClass/FalseClass
|
55
|
+
def to_boolean
|
56
|
+
|
57
|
+
if /^(true|false)$/i.match( self.to_s )
|
58
|
+
|
59
|
+
$1.downcase == 'true'
|
60
|
+
|
61
|
+
else
|
62
|
+
|
63
|
+
#default
|
64
|
+
Kernel::raise TypeError.new( "Unable to convert string \"#{ self }\" to boolean (Expected \”true\" or \"false\")" )
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
20
72
|
module MobyUtil
|
21
73
|
|
22
74
|
class StringHelper
|
@@ -29,7 +81,8 @@ module MobyUtil
|
|
29
81
|
def self.boolean?( string )
|
30
82
|
|
31
83
|
# raise exception if argument type other than String
|
32
|
-
Kernel::raise ArgumentError.new("Invalid argument format %s (Expected: %s)" % [ string.class, "String" ]) unless string.kind_of?( String )
|
84
|
+
#Kernel::raise ArgumentError.new("Invalid argument format %s (Expected: %s)" % [ string.class, "String" ]) unless string.kind_of?( String )
|
85
|
+
string.check_type( String, "Wrong argument type $1 (Expected $2)" )
|
33
86
|
|
34
87
|
/^(true|false)$/i.match( string ).kind_of?( MatchData )
|
35
88
|
|
@@ -46,7 +99,7 @@ module MobyUtil
|
|
46
99
|
|
47
100
|
Kernel::raise ArgumentError.new("Invalid argument format %s (Expected: %s)" % [ string.class, "String" ]) unless string.kind_of?( String )
|
48
101
|
|
49
|
-
|
102
|
+
/^[0-9]+$/.match( string ).kind_of?( MatchData )
|
50
103
|
|
51
104
|
end
|
52
105
|
|
@@ -18,171 +18,204 @@
|
|
18
18
|
############################################################################
|
19
19
|
|
20
20
|
# Utility for handling database connections
|
21
|
-
|
22
21
|
module MobyUtil
|
23
22
|
|
24
|
-
|
23
|
+
class DBAccess
|
25
24
|
|
26
25
|
DB_TYPE_MYSQL = 'mysql'
|
27
26
|
DB_TYPE_SQLITE = 'sqlite'
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
28
|
+
include Singleton
|
29
|
+
|
30
|
+
# == description
|
31
|
+
# Initialize the singleton
|
32
|
+
# connection is maintained as long as the connectivity parameters remain the same
|
33
|
+
# this is to avoid constant connect as this takes time
|
34
|
+
#
|
35
|
+
def initialize
|
36
|
+
@@_connections = {}
|
37
|
+
@@_mysql = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# == description
|
41
|
+
# Class Method that returns existing connections
|
42
|
+
#
|
43
|
+
def DBAccess.connections()
|
44
|
+
return @@_connections
|
45
|
+
end
|
46
|
+
|
47
|
+
# == description
|
48
|
+
# Runs an SQL query on the on the given MobyUtil::DBConnection
|
49
|
+
#
|
50
|
+
# == arguments
|
51
|
+
# dbc
|
52
|
+
# MobyUtil::DBConnection
|
53
|
+
# description: object with the connection details of an open sql connection
|
54
|
+
#
|
55
|
+
# query_string
|
56
|
+
# String
|
57
|
+
# description: database-specific SQL query (note that mysql and sqlite have slightly different syntax)
|
58
|
+
# example: "select * from tdriver_locale;"
|
59
|
+
#
|
60
|
+
# == returns
|
61
|
+
# Array
|
62
|
+
# description: Array of rows returned by the server. Each row is an array of String values.
|
63
|
+
#
|
64
|
+
# == throws
|
65
|
+
# ArgumentError
|
66
|
+
# description: if the argument provided is not the right object type
|
67
|
+
#
|
68
|
+
def self.query( dbc, query_string )
|
69
|
+
# Create first instance of this class if it doesn't exist
|
70
|
+
self.instance
|
71
|
+
|
72
|
+
#raise ArgumentError.new("Invalid connection object provided.") if dbc.nil? or !dbc.kind_of? MobyUtil::DBConnection
|
73
|
+
dbc.check_type( MobyUtil::DBConnection, "Wrong argument type $1 for database connection object (expected $2)" )
|
74
|
+
|
75
|
+
#raise ArgumentError.new("The query qtring must be provided as a non empty string.") if query_string.nil? or query_string.class != String or query_string.empty?
|
76
|
+
query_string.check_type( String, "Wrong variable type $1 for database query string (expected $2)")
|
77
|
+
query_string.not_empty( "Database query string must not be empty string" )
|
78
|
+
|
79
|
+
db_type = dbc.db_type
|
80
|
+
host = dbc.host
|
81
|
+
username = dbc.username
|
82
|
+
password = dbc.password
|
83
|
+
database_name = dbc.database_name
|
84
|
+
|
85
|
+
# Check creation parameters
|
86
|
+
|
87
|
+
#raise DbTypeNotDefinedError.new( "Database type need to be either 'mysql' or 'sqlite'!" ) if db_type == nil
|
88
|
+
db_type.check_type( String, "Wrong argument type $1 for database type (expected $2)" )
|
89
|
+
|
90
|
+
#raise DbTypeNotSupportedError.new( "Database type '#{db_type}' not supported! Type need to be either 'mysql' or 'sqlite'!" ) unless db_type == DB_TYPE_MYSQL or db_type == DB_TYPE_SQLITE
|
91
|
+
db_type.validate( [ DB_TYPE_MYSQL, DB_TYPE_SQLITE ], "Unsupported database type $1 (expected $2)" )
|
92
|
+
|
93
|
+
if ( db_type == DB_TYPE_MYSQL )
|
94
|
+
|
95
|
+
# raise ArgumentError.new("Host must be provided as a non empty string.") if host.nil? or host.class != String or host.empty?
|
96
|
+
host.check_type( String, "Wrong variable type $1 for host (expected $2)" )
|
97
|
+
host.not_empty( "Host must not be empty string" )
|
98
|
+
|
99
|
+
#raise ArgumentError.new("Username must be provided as a non empty string.") if username.nil? or username.class != String or username.empty?
|
100
|
+
username.check_type( String, "Wrong variable type $1 for username (expected $2)" )
|
101
|
+
username.not_empty( "Username must not be empty string" )
|
102
|
+
|
103
|
+
#raise ArgumentError.new("Password must be provided as a string.") if password.nil? or password.class != String
|
104
|
+
password.check_type( String, "Wrong variable type $1 for password (expected $2)")
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
#raise ArgumentError.new("The database name must be provided as a non empty string.") if database_name.nil? or database_name.class != String or database_name.empty?
|
109
|
+
database_name.check_type( String, "Wrong variable type $1 for database name (expected $2)" )
|
110
|
+
database_name.not_empty( "Database name must not be empty string" )
|
111
|
+
|
112
|
+
# Check for exsting connection for that host and create it if needed
|
113
|
+
if !@@_connections.has_key?( host + db_type + database_name ) # make connection ID unique by using host, type and db on the key
|
114
|
+
dbc.dbh = connect_db( db_type, host, username, password, database_name )
|
115
|
+
@@_connections[ host + db_type + database_name ] = dbc
|
116
|
+
end
|
117
|
+
|
118
|
+
if db_type == DB_TYPE_MYSQL
|
119
|
+
|
120
|
+
query_result = @@_connections[ host + db_type + database_name ].dbh.query( query_string ) # identical?
|
121
|
+
|
122
|
+
elsif dbc.db_type == DB_TYPE_SQLITE
|
123
|
+
|
124
|
+
query_result = @@_connections[ host + db_type + database_name ].dbh.query( query_string ) # identical?
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# Return a uniform set of results as an array of rows, rows beeing an array of values ( Array<Array<String>> )
|
129
|
+
result = []
|
130
|
+
|
131
|
+
if db_type == DB_TYPE_MYSQL and !query_result.nil?
|
132
|
+
|
133
|
+
query_result.num_rows.times do |i|
|
134
|
+
|
135
|
+
result << query_result.fetch_row
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
elsif db_type == DB_TYPE_SQLITE and !query_result.nil?
|
140
|
+
|
141
|
+
# Create Array<SQLite3::ResultSet::ArrayWithTypesAndFields<String>> type result
|
142
|
+
# it effectively behaves the same as with Array<Array<String>> but the inner Arrays have .fields and .types properties
|
143
|
+
# which return the column name and type for each value on the row (Array) returned.
|
144
|
+
while ( row = query_result.next )
|
145
|
+
result << row
|
146
|
+
end
|
147
|
+
|
148
|
+
# it is essentially a prepare method so we need to call close to free the connection
|
149
|
+
query_result.close
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
result
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
# == description
|
158
|
+
# Retunrs the number of affected rows on the latest sql query on the given MobyUtil::DBConnection
|
159
|
+
#
|
160
|
+
# == arguments
|
161
|
+
# dbc
|
162
|
+
# MobyUtil::DBConnection
|
163
|
+
# description: object with the connection details of an open sql connection
|
164
|
+
#
|
165
|
+
# == returns
|
166
|
+
# Integer
|
167
|
+
# description: number of rows affected
|
168
|
+
#
|
169
|
+
# == throws
|
170
|
+
# ArgumentError
|
171
|
+
# description: if the argument provided is not the right object type
|
172
|
+
#
|
173
|
+
def self.affected_rows(dbc)
|
174
|
+
|
175
|
+
#raise ArgumentError.new("Invalid connection object provided.") if dbc.nil? or !dbc.kind_of? MobyUtil::DBConnection
|
176
|
+
dbc.check_type( MobyUtil::DBConnection, "Wrong argument type $1 for database connection object (expected $2)" )
|
177
|
+
|
178
|
+
# Check for exsting connection for that host and create it if needed
|
179
|
+
if !@@_connections.has_key?( dbc.host + dbc.db_type + dbc.database_name ) # make connection ID unique by using host, type and db on the key
|
180
|
+
dbc.dbh = connect_db( dbc.db_type, dbc.host, dbc.username, dbc.password, dbc.database_name )
|
181
|
+
@@_connections[ dbc.host + dbc.db_type + dbc.database_name ] = dbc
|
182
|
+
end
|
183
|
+
result = 0
|
184
|
+
if dbc.db_type == DB_TYPE_MYSQL
|
185
|
+
result = @@_connections[ dbc.host + dbc.db_type + dbc.database_name ].dbh.affected_rows
|
186
|
+
elsif dbc.db_type == DB_TYPE_SQLITE
|
187
|
+
result = @@_connections[ dbc.host + dbc.db_type + dbc.database_name ].dbh.changes
|
188
|
+
end
|
189
|
+
return result
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
# == description
|
195
|
+
# Function establishes a new connection to as sql server and returns it's handle
|
196
|
+
#
|
197
|
+
def self.connect_db( db_type, host, username, password, database_name )
|
198
|
+
|
199
|
+
# if mysql API and connection are not initialized, then initialize the mysql API
|
200
|
+
if ( db_type == DB_TYPE_MYSQL ) && ( @@_mysql.nil? )
|
201
|
+
require 'mysql'
|
202
|
+
@@_mysql = Mysql::init
|
203
|
+
elsif db_type == DB_TYPE_SQLITE
|
204
|
+
require 'sqlite3'
|
205
|
+
end
|
206
|
+
|
207
|
+
begin
|
208
|
+
dbh = @@_mysql.connect( host, username, password, database_name) if db_type == DB_TYPE_MYSQL
|
209
|
+
dbh.query 'SET NAMES utf8' if db_type == DB_TYPE_MYSQL # set the utf8 encoding
|
210
|
+
dbh = SQLite3::Database.new( database_name ) if db_type == DB_TYPE_SQLITE
|
211
|
+
rescue
|
212
|
+
raise SqlConnectError.new( $!.message )
|
213
|
+
end
|
214
|
+
|
215
|
+
return dbh
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
end # DBAccess
|
188
220
|
|
221
|
+
end # MobyUtil
|