imparcial 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/lib/imparcial/driver/base/expression/base.rb +104 -0
  2. data/lib/imparcial/driver/base/expression/delete.rb +72 -0
  3. data/lib/imparcial/driver/base/expression/index.rb +199 -0
  4. data/lib/imparcial/driver/base/expression/insert.rb +33 -0
  5. data/lib/imparcial/driver/base/expression/lock.rb +11 -0
  6. data/lib/imparcial/driver/base/expression/select.rb +36 -0
  7. data/lib/imparcial/driver/base/expression/sequence.rb +189 -0
  8. data/lib/imparcial/driver/base/expression/statement.rb +128 -0
  9. data/lib/imparcial/driver/base/expression/table_diff.rb +154 -0
  10. data/lib/imparcial/driver/base/expression/table_evolution.rb +94 -0
  11. data/lib/imparcial/driver/base/expression/table_metadata.rb +122 -0
  12. data/lib/imparcial/driver/base/expression/table_operation.rb +137 -0
  13. data/lib/imparcial/driver/base/expression/transaction.rb +59 -0
  14. data/lib/imparcial/driver/base/expression/update.rb +33 -0
  15. data/lib/imparcial/driver/base/expression/util.rb +45 -0
  16. data/lib/imparcial/driver/base/expression.rb +37 -0
  17. data/lib/imparcial/driver/base/result.rb +94 -0
  18. data/lib/imparcial/driver/base/sql/delete.rb +22 -0
  19. data/lib/imparcial/driver/base/sql/index.rb +53 -0
  20. data/lib/imparcial/driver/base/sql/insert.rb +63 -0
  21. data/lib/imparcial/driver/base/sql/select.rb +101 -0
  22. data/lib/imparcial/driver/base/sql/sequence.rb +55 -0
  23. data/lib/imparcial/driver/base/sql/table_metadata.rb +29 -0
  24. data/lib/imparcial/driver/base/sql/table_operation.rb +49 -0
  25. data/lib/imparcial/driver/base/sql/transaction.rb +43 -0
  26. data/lib/imparcial/driver/base/sql/update.rb +29 -0
  27. data/lib/imparcial/driver/base/sql.rb +25 -0
  28. data/lib/imparcial/driver/base/typemap.rb +214 -0
  29. data/lib/imparcial/driver/base/util.rb +41 -0
  30. data/lib/imparcial/driver/base.rb +156 -0
  31. data/lib/imparcial/driver/mysql/expression/index.rb +44 -0
  32. data/lib/imparcial/driver/mysql/expression/table.rb +26 -0
  33. data/lib/imparcial/driver/mysql/expression.rb +11 -0
  34. data/lib/imparcial/driver/mysql/result.rb +33 -0
  35. data/lib/imparcial/driver/mysql/sql/index.rb +51 -0
  36. data/lib/imparcial/driver/mysql/sql/sequence.rb +39 -0
  37. data/lib/imparcial/driver/mysql/sql/table_metadata.rb +43 -0
  38. data/lib/imparcial/driver/mysql/sql/table_operation.rb +20 -0
  39. data/lib/imparcial/driver/mysql/sql.rb +15 -0
  40. data/lib/imparcial/driver/mysql/typemap.rb +13 -0
  41. data/lib/imparcial/driver/mysql/util.rb +13 -0
  42. data/lib/imparcial/driver/mysql.rb +48 -0
  43. data/lib/imparcial/driver/postgre/expression/index.rb +10 -0
  44. data/lib/imparcial/driver/postgre/expression/sequence.rb +9 -0
  45. data/lib/imparcial/driver/postgre/expression/table.rb +20 -0
  46. data/lib/imparcial/driver/postgre/expression.rb +13 -0
  47. data/lib/imparcial/driver/postgre/result.rb +35 -0
  48. data/lib/imparcial/driver/postgre/sql/index.rb +53 -0
  49. data/lib/imparcial/driver/postgre/sql/sequence.rb +28 -0
  50. data/lib/imparcial/driver/postgre/sql/table_metadata.rb +46 -0
  51. data/lib/imparcial/driver/postgre/sql/table_operation.rb +9 -0
  52. data/lib/imparcial/driver/postgre/sql.rb +15 -0
  53. data/lib/imparcial/driver/postgre/typemap.rb +29 -0
  54. data/lib/imparcial/driver/postgre/util.rb +19 -0
  55. data/lib/imparcial/driver/postgre.rb +43 -0
  56. data/lib/imparcial/driver.rb +1 -0
  57. data/lib/imparcial/exception.rb +61 -0
  58. data/lib/imparcial.rb +82 -0
  59. metadata +114 -0
@@ -0,0 +1,128 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module Statement
5
+
6
+ private
7
+
8
+ def parse_conditions ( conditions )
9
+
10
+ # No condition? no evaluation!
11
+
12
+ return '' unless conditions
13
+
14
+ ref = ' WHERE '
15
+
16
+ # ['id = ?', 1]
17
+ # ^ ^
18
+ # | |
19
+ # syntax values
20
+
21
+ syntax = conditions[0]
22
+ values = conditions[1..-1]
23
+
24
+ # Extract all args.
25
+ #
26
+ # for example:
27
+ #
28
+ # 'id = ? AND name = ?'
29
+ #
30
+ # It has two args:
31
+ # id = ?
32
+ # name = ?
33
+
34
+ ops = '=|!=|>|<|>=|<=|<>|IN|NOT IN'
35
+ aps = "\"\'"
36
+ log = "AND|OR"
37
+
38
+ args = syntax.scan(/([\w|\.]+) ?(#{ops}) ?(\?|[#{aps}]?[\w|\d]+[#{aps}]?) ?(#{log})?/)
39
+ index = -1
40
+
41
+ args.each do |arg|
42
+
43
+ name, operator, value, logical = arg
44
+
45
+ if value != '?'
46
+
47
+ column = quote(name) + ' ' + operator + ' ' + value
48
+ column += ' ' + logical + ' ' if logical
49
+ ref += column
50
+ next
51
+
52
+ end
53
+
54
+ index += 1
55
+
56
+ if values[index].class == Array
57
+
58
+ raise ConditionError if values[index].length == 0
59
+
60
+ op = 'IN' if operator == '='
61
+ op = 'NOT IN' if operator == '!='
62
+ column = quote(name) + " #{op} ("
63
+
64
+ for i in 0..values[index].length-1
65
+ values[index][i] = quote_value(values[index][i])
66
+ end
67
+
68
+ column += values[index].join(',')
69
+
70
+ column += ')'
71
+ column += ' ' + logical + ' ' if logical
72
+
73
+ ref += column
74
+
75
+ else
76
+
77
+ value = values[index] || 'NULL'
78
+ value = quote_value(value)
79
+
80
+ column = quote(name) + ' ' + operator + ' ' + value
81
+ column += ' ' + logical + ' ' if logical
82
+
83
+ ref += column
84
+
85
+ end
86
+
87
+ end #end of args.each
88
+
89
+ ref
90
+
91
+ end # end of parse_condition
92
+
93
+ def parse_limit ( limit )
94
+
95
+ # No limit? no evaluation!
96
+
97
+ return '' unless limit
98
+
99
+ if limit.class != Range
100
+
101
+ ' LIMIT ' + limit.to_s
102
+
103
+ else
104
+
105
+ ' LIMIT ' + limit.first.to_i.to_s + ',' + limit.last.to_i.to_s
106
+
107
+ end
108
+
109
+ end
110
+
111
+ def parse_order ( options )
112
+
113
+ # No order? no evaluation!
114
+
115
+ return '' if !options[:order_desc] && !options[:order_asc]
116
+
117
+ syntax = ' ORDER BY '
118
+ syntax += quote( options[:order_desc] || options[:order_asc])
119
+ syntax += options[:order_desc] ? ' DESC' : ' ASC'
120
+
121
+ syntax
122
+
123
+ end
124
+
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,154 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module TableDiff
5
+
6
+ private
7
+
8
+ def expected_options_for_reporting
9
+
10
+ {:table_name => :required, :fields => :required}
11
+
12
+ end
13
+
14
+ public
15
+
16
+ def diff_columns ( options = {} )
17
+
18
+ modified = report_modified_columns options
19
+ new = report_new_columns options
20
+ old = report_old_columns options
21
+
22
+ [modified, new, old]
23
+
24
+ end
25
+
26
+ # Execute a diff by comparing existent fields.
27
+ # If you eventually try to insert a non-existent field,
28
+ # an exception shall be raised.
29
+
30
+ def report_modified_columns ( options = {} )
31
+
32
+ check_options expected_options_for_reporting, options
33
+
34
+ modified_fields = options[:fields]
35
+
36
+ modified_columns = []
37
+ current_fields = retrieve_columns :table_name => options[:table_name]
38
+
39
+ parse_fields modified_fields do |modified_field|
40
+
41
+ current_fields.each do |current_field|
42
+
43
+ if modified_field[:name] == current_field[:name]
44
+
45
+ # We gotta check every attribute to see if a modification can occur.
46
+
47
+ if modified_field[:type] != current_field[:type] || modified_field[:default_value] != current_field[:default_value]\
48
+ || modified_field[:allow_null] != current_field[:allow_null] || modified_field[:pk] != current_field[:pk]\
49
+ || modified_field[:sequence] != current_field[:sequenec] || modified_field[:size] != current_field[:size]
50
+
51
+ modified_columns << current_field
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end #end of parse_fields
60
+
61
+ modified_columns
62
+
63
+ end
64
+
65
+ # Execute a diff by comparing new fields.
66
+ # If you eventually try to insert an existent field,
67
+ # an exception shall be raised.
68
+
69
+ def report_new_columns ( options = {} )
70
+
71
+ check_options expected_options_for_reporting, options
72
+
73
+ new_fields = options[:fields]
74
+
75
+ new_columns = []
76
+ no_new_field = false
77
+
78
+ current_fields = retrieve_columns :table_name => options[:table_name]
79
+
80
+ parse_fields new_fields do |new_field|
81
+
82
+ current_fields.each do |current_field|
83
+
84
+ if new_field[:name] == current_field[:name]
85
+
86
+ no_new_field = true
87
+ break
88
+
89
+ end
90
+
91
+ end
92
+
93
+ if no_new_field
94
+
95
+ no_new_field = false
96
+ next
97
+
98
+ end
99
+
100
+ new_columns << new_field
101
+
102
+ end
103
+
104
+ new_columns
105
+
106
+ end
107
+
108
+ # Execute a diff by comparing new fields with current ones.
109
+ # Legacy fields will be showed.
110
+ # Shall be raised an exception if trying to compare modifying fields.
111
+
112
+ def report_old_columns ( options )
113
+
114
+ check_options expected_options_for_reporting, options
115
+
116
+ new_fields = options[:fields]
117
+
118
+ legacy_fields = []
119
+ no_old_field = false
120
+
121
+ current_fields = retrieve_columns :table_name => options[:table_name]
122
+
123
+ current_fields.each do |current_field|
124
+
125
+ parse_fields new_fields do |new_field|
126
+
127
+ if new_field[:name] == current_field[:name]
128
+
129
+ no_old_field = true
130
+ break
131
+
132
+ end
133
+
134
+ if no_old_field == true
135
+
136
+ no_old_field = false
137
+ next
138
+
139
+ end
140
+
141
+ legacy_fields << current_field
142
+
143
+ end #end of parse_fields
144
+
145
+ end
146
+
147
+ legacy_fields
148
+
149
+ end
150
+
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,94 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module TableEvolution
5
+
6
+ =begin
7
+ # Execute the alter table statement by only insert new fields.
8
+ # An exception shall be raised if trying to insert modified fields.
9
+
10
+ def add_columns ( table_name, fields )
11
+
12
+ # Let's see if it's necessary to alter a table.
13
+
14
+ affected_columns = report_new_columns table_name, fields, true
15
+
16
+ syntax = ''
17
+
18
+ if affected_columns.length > 0
19
+
20
+ syntax += 'ALTER TABLE ' + quote_table(table_name) + ' ADD COLUMN'
21
+ syntax += '('
22
+
23
+ fields_to_columns affected_columns do |column|
24
+
25
+ syntax += column + ','
26
+
27
+ end
28
+
29
+ syntax.chop!
30
+
31
+ syntax += ')'
32
+
33
+ end
34
+
35
+ query syntax
36
+
37
+ syntax
38
+
39
+ end
40
+
41
+ def drop_columns ( table_name, fields_by_name )
42
+
43
+ syntax = ''
44
+
45
+ if fields_by_name.length > 0
46
+
47
+ syntax += 'ALTER TABLE ' + quote_table(table_name)
48
+
49
+ fields_by_name.each do |name|
50
+
51
+ syntax += ' DROP COLUMN ' + quote_column(name) + ','
52
+
53
+ end
54
+
55
+ syntax.chop!
56
+
57
+ end
58
+
59
+ begin
60
+
61
+ query syntax
62
+
63
+ rescue Object => ex
64
+
65
+ raise TableError.new(ex.message)
66
+
67
+ end
68
+
69
+ syntax
70
+
71
+ end
72
+
73
+ def modify_columns ( table_name, fields )
74
+
75
+ syntax = 'ALTER TABLE ' + quote_table(table_name) + ' '
76
+
77
+ fields_to_columns fields do |column|
78
+
79
+ syntax += 'MODIFY COLUMN ' + column + ','
80
+
81
+ end
82
+
83
+ syntax.chop!
84
+
85
+ query syntax
86
+
87
+ syntax
88
+
89
+ end
90
+ =end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,122 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module TableMetadata
5
+
6
+ private
7
+
8
+ def expected_options_for_retrieving_columns
9
+
10
+ {:table_name => :required}
11
+
12
+ end
13
+
14
+ def expected_options_for_verifying_existence
15
+
16
+ {:table_name => :required}
17
+
18
+ end
19
+
20
+ ###########################################
21
+ # #
22
+ # Couple of Table features #
23
+ # #
24
+ ###########################################
25
+
26
+ public
27
+
28
+ # Return all avaliable tables by name in a specific database
29
+ # Return is a array of names.
30
+
31
+ def retrieve_tables
32
+
33
+ query sql_for_retrieving_tables
34
+
35
+ tables = []
36
+
37
+ result.fetch do |table_name_column|
38
+
39
+ tables << table_name_column.value
40
+
41
+ end
42
+
43
+ tables
44
+
45
+ rescue adapter_specific_exception => ex
46
+
47
+ raise TableRetrieveError.new(ex.message)
48
+
49
+ end
50
+
51
+ # Check if a table exists, returning true or false.
52
+
53
+ def table_exists? ( options = {} )
54
+
55
+ check_options expected_options_for_verifying_existence, options
56
+
57
+ tables = retrieve_tables
58
+
59
+ tables.each do |name|
60
+
61
+ return true if name == options[:table_name]
62
+
63
+ end
64
+
65
+ return false
66
+
67
+ end
68
+
69
+ # The opposite of above.
70
+
71
+ def table_not_exists? ( options = {} )
72
+
73
+ not table_exists? options
74
+
75
+ end
76
+
77
+ public
78
+
79
+ # Return metadata about columns from a specific table.
80
+ # It Requires a table name as parameter.
81
+ # If there's no table, it will raise an error.
82
+
83
+ def retrieve_columns ( options = {} )
84
+
85
+ check_options expected_options_for_retrieving_columns, options
86
+
87
+ query sql_for_retrieving_columns( options )
88
+
89
+ columns = []
90
+
91
+ result.fetch do |name, type, size, allow_null, pk, default_value, auto_inc, indexed|
92
+
93
+ column = {}
94
+ column[:name] = name.value
95
+ column[:type] = type.value
96
+ column[:size] = size.value
97
+ column[:allow_null] = allow_null.value
98
+ column[:pk] = pk.value
99
+ column[:default_value] = default_value.value
100
+ column[:auto_increment] = auto_inc.value
101
+ column[:indexed] = indexed.value
102
+
103
+ # Transform SQL columns into RDBAL's ones.
104
+
105
+ parse_column column
106
+
107
+ columns << column
108
+
109
+ end
110
+
111
+ columns
112
+
113
+ rescue adapter_specific_exception => ex
114
+
115
+ raise TableRetrieveError.new(ex.message)
116
+
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,137 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module TableOperation
5
+
6
+ private
7
+
8
+ def expected_options_for_creating_table
9
+
10
+ {:table_name => :required, :fields => :required}
11
+
12
+ end
13
+
14
+ def expected_options_for_dropping_table
15
+
16
+ {:table_name => :required}
17
+
18
+ end
19
+
20
+ ###########################################
21
+ # #
22
+ # Dropping Table #
23
+ # #
24
+ ###########################################
25
+
26
+ public
27
+
28
+ # Drop a table by table_name.
29
+ # An exception will be raised if nothing is found.
30
+ # Usage:
31
+ # drop_table :table_name => 'something'
32
+
33
+ def drop_table ( options = {} )
34
+
35
+ check_options expected_options_for_dropping_table, options
36
+
37
+ query sql_for_dropping_table( options )
38
+
39
+ rescue adapter_specific_exception => ex
40
+
41
+ raise TableDropError.new(ex.message)
42
+
43
+ end
44
+
45
+ # Drop a table by name.
46
+ # An exception shall not be raised independently of what happens.
47
+
48
+ def drop_table_if_necessary ( options = {} )
49
+
50
+ drop_table options
51
+
52
+ rescue TableDropError; end
53
+
54
+ # Drop all tables.
55
+
56
+ def drop_all_tables
57
+
58
+ for table_name in retrieve_tables
59
+
60
+ query sql_for_dropping_table( {:table_name => table_name} )
61
+
62
+ end
63
+
64
+ rescue adapter_specific_exception => ex
65
+
66
+ raise TableDropError.new(ex.message)
67
+
68
+ end
69
+
70
+ ###########################################
71
+ # #
72
+ # Creating Table #
73
+ # #
74
+ ###########################################
75
+
76
+ private
77
+
78
+ def column_format
79
+
80
+ [:name, :type, :size, :allow_null, :auto_increment, :default_value]
81
+
82
+ end
83
+
84
+ def build_column ( field )
85
+
86
+ raise OptionError unless field
87
+
88
+ # Fill it up with default values if needed.
89
+
90
+ parse_field field
91
+ sql_column = field_to_column field
92
+
93
+ syntax = ''
94
+
95
+ for attr in column_format
96
+
97
+ syntax += sql_column[attr] + ' ' if sql_column[attr]
98
+
99
+ end
100
+
101
+ syntax
102
+
103
+ end
104
+
105
+ def field_to_column ( field )
106
+
107
+ column = {}
108
+ column[:name] = quote(field[:name])
109
+ column[:type] = regular_types[field[:type]]
110
+ column[:size] = '(' + quote_value(field[:size]) + ')' if field[:size]
111
+ column[:allow_null] = field[:allow_null] == true ? 'NULL' : 'NOT NULL'
112
+ column[:default_value] = field[:default_value] != nil ? ' DEFAULT ' + quote_value(field[:default_value]) : ''
113
+
114
+ column
115
+
116
+ end
117
+
118
+ public
119
+
120
+ # Create a table.
121
+
122
+ def create_table ( options = {} )
123
+
124
+ check_options expected_options_for_creating_table, options
125
+
126
+ query sql_for_creating_table( options )
127
+
128
+ rescue adapter_specific_exception => ex
129
+
130
+ raise TableCreateError.new(ex.message)
131
+
132
+ end
133
+
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,59 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module Transaction
5
+
6
+ public
7
+
8
+ # Create a savepoint for a transaction.
9
+
10
+ def create_savepoint ( name )
11
+
12
+ query sql_for_saving_point( name )
13
+
14
+ rescue adapter_specific_exception => ex
15
+
16
+ raise TransactionError.new(ex.message)
17
+
18
+ end
19
+
20
+ # Rollback a transaction to the specified savepoint.
21
+
22
+ def restore_savepoint ( name )
23
+
24
+ query sql_for_rolling_back( name )
25
+
26
+ rescue adapter_specific_exception => ex
27
+
28
+ raise TransactionError.new(ex.message)
29
+
30
+ end
31
+
32
+ # Initialize a transaction.
33
+
34
+ def initialize_transaction
35
+
36
+ query sql_for_initializing_a_transaction
37
+
38
+ rescue adapter_specific_exception => ex
39
+
40
+ raise TransactionError.new(ex.message)
41
+
42
+ end
43
+
44
+ # Finalize a transaction.
45
+
46
+ def terminate_transaction
47
+
48
+ query sql_for_terminating_a_transaction
49
+
50
+ rescue adapter_specific_exception => ex
51
+
52
+ raise TransactionError.new(ex.message)
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end