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,33 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module Update
5
+
6
+ private
7
+
8
+ def expected_options_for_updating
9
+
10
+ {:table_name => :required, :values => :required, :conditions => :required}
11
+
12
+ end
13
+
14
+ public
15
+
16
+ # Update a table.
17
+
18
+ def update ( options )
19
+
20
+ check_options expected_options_for_updating, options
21
+
22
+ query sql_for_updating( options )
23
+
24
+ rescue adapter_specific_exception => ex
25
+
26
+ raise UpdateError.new(ex.message)
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,45 @@
1
+ module Imparcial
2
+ module Driver
3
+ module ExpressionBase
4
+ module Util
5
+
6
+ private
7
+
8
+ # Execute SQL statement for couting records of a table.
9
+
10
+ def sql_for_couting_records ( options )
11
+
12
+ 'SELECT COUNT(*) FROM ' + quote(options[:table_name])
13
+
14
+ end
15
+
16
+ def expected_options_for_total_of_records
17
+
18
+ {:table_name => :required}
19
+
20
+ end
21
+
22
+ public
23
+
24
+ # Retrieve the total of records in a table.
25
+
26
+ def total_of_records ( options = {} )
27
+
28
+ check_options expected_options_for_total_of_records, options
29
+
30
+ query sql_for_couting_records( options )
31
+
32
+ result.fetch_first_row.value
33
+
34
+ rescue adapter_specific_exception => ex
35
+
36
+ raise ExpressionError.new(ex.message)
37
+
38
+ end
39
+ alias_method :num_of_records, :total_of_records
40
+
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'imparcial/driver/base/expression/base'
2
+ require 'imparcial/driver/base/expression/statement'
3
+ require 'imparcial/driver/base/expression/sequence'
4
+ require 'imparcial/driver/base/expression/table_diff'
5
+ require 'imparcial/driver/base/expression/table_operation'
6
+ require 'imparcial/driver/base/expression/table_metadata'
7
+ require 'imparcial/driver/base/expression/table_evolution'
8
+ require 'imparcial/driver/base/expression/insert'
9
+ require 'imparcial/driver/base/expression/select'
10
+ require 'imparcial/driver/base/expression/delete'
11
+ require 'imparcial/driver/base/expression/update'
12
+ require 'imparcial/driver/base/expression/util'
13
+ require 'imparcial/driver/base/expression/lock'
14
+ require 'imparcial/driver/base/expression/transaction'
15
+ require 'imparcial/driver/base/expression/index'
16
+
17
+ module Imparcial
18
+ module Driver
19
+ module ExpressionBase
20
+ include Base
21
+ include Statement
22
+ include Sequence
23
+ include TableDiff
24
+ include TableOperation
25
+ include TableMetadata
26
+ include TableEvolution
27
+ include Insert
28
+ include Select
29
+ include Delete
30
+ include Update
31
+ include Util
32
+ include Lock
33
+ include Transaction
34
+ include Index
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,94 @@
1
+ module Imparcial
2
+ module Driver
3
+
4
+ # This class will serve as base for adapter specific result class.
5
+
6
+ class ResultBase
7
+ attr_reader :specific
8
+
9
+ def initialize ( result_specific )
10
+
11
+ @specific = result_specific
12
+
13
+ end
14
+
15
+ # Subclasses need to override this method.
16
+
17
+ def rows
18
+
19
+ raise FeatureNotFound
20
+
21
+ end
22
+
23
+ # Subclasses need to override this method.
24
+
25
+ def fetch
26
+
27
+ raise FeatureNotFound
28
+
29
+ end
30
+
31
+ # Fetch result in array form.
32
+
33
+ def fetch_in_array
34
+
35
+ array = []
36
+
37
+ fetch do |*all|
38
+
39
+ array << all
40
+
41
+ end
42
+
43
+ array
44
+
45
+ end
46
+
47
+ # Fetch only the first row
48
+
49
+ def fetch_first_row
50
+
51
+ fetch do |*rows|
52
+ return *rows
53
+ end
54
+
55
+ end
56
+
57
+
58
+ end
59
+
60
+ # This class wraps a row.
61
+ # Usually, a row will only come with value.
62
+ # Instead, we can also keep the column name. So that, this class
63
+ # can keep track of column name and value.
64
+ #
65
+ # -------------------
66
+ # id | name | price <- column name
67
+ # 1 | apple | 0.99 <- column value
68
+ # 2 | lemon | 1.99 <- column value
69
+ # -------------------
70
+
71
+ class Row
72
+ include Imparcial::Driver::UtilBase
73
+
74
+ attr_accessor :name, :value
75
+ alias_method :column_name, :name
76
+ alias_method :column_value, :value
77
+
78
+ def initialize ( column_name, column_value )
79
+
80
+ @name = column_name
81
+ @value = unquote_value(column_value)
82
+
83
+ end
84
+
85
+ def to_s
86
+
87
+ @value
88
+
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,22 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Delete
5
+
6
+ private
7
+
8
+ # SQL for generating the delete statement.
9
+
10
+ def sql_for_deleting ( options )
11
+
12
+ syntax = 'DELETE FROM ' + quote(options[:table_name])
13
+ syntax += parse_conditions options[:conditions] if options[:conditions]
14
+
15
+ syntax
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,53 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Index
5
+
6
+ private
7
+
8
+ # Generate SQL statement for creating an index.
9
+
10
+ def sql_for_creating_index ( options )
11
+
12
+ syntax = 'CREATE '
13
+ syntax += options[:index_type] + ' ' if options[:index_type]
14
+ syntax += 'INDEX '
15
+ syntax += options[:index_name] + ' '
16
+ syntax += 'ON ' + quote(options[:table_name])
17
+ syntax += '('
18
+ syntax += quote(options[:column_name])
19
+ syntax += ')'
20
+
21
+ syntax
22
+
23
+ end
24
+
25
+ # Generate SQL statement for dropping an index.
26
+
27
+ def sql_for_dropping_index ( options )
28
+
29
+ 'DROP INDEX ' + options[:index_name]
30
+
31
+ end
32
+
33
+ # Subclasses need to override this method.
34
+
35
+ def sql_for_retrieving_indexes
36
+
37
+ raise FeatureNotFound
38
+
39
+ end
40
+
41
+ # Subclasses need to override this method.
42
+
43
+ def sql_for_retrieving_indexes_for_table ( options )
44
+
45
+ raise FeatureNotFound
46
+
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,63 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Insert
5
+
6
+ private
7
+
8
+ # Some helpers for inserting method.
9
+ # Extract column names from a hash.
10
+
11
+ def column_names_for ( values )
12
+
13
+ column_names = []
14
+
15
+ values.each_key do |column_name|
16
+
17
+ column_names << quote(column_name)
18
+
19
+ end
20
+
21
+ column_names
22
+
23
+ end
24
+
25
+ # Extract column values from a hash.
26
+
27
+ def column_values_for ( values )
28
+
29
+ column_values = []
30
+
31
+ values.each_value do |column_value|
32
+
33
+ column_values << quote_value(column_value)
34
+
35
+ end
36
+
37
+ column_values
38
+
39
+ end
40
+
41
+ # Execute the SQL statement for inserting.
42
+
43
+ def sql_for_inserting ( options )
44
+
45
+ syntax = 'INSERT INTO ' + quote(options[:table_name])
46
+ syntax += '('
47
+
48
+ syntax += column_names_for(options[:values]).join(',')
49
+
50
+ syntax += ') VALUES ('
51
+
52
+ syntax += column_values_for(options[:values]).join(',')
53
+
54
+ syntax += ')'
55
+
56
+ syntax
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,101 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Select
5
+
6
+ private
7
+
8
+ def get_key ( name, table_metadata )
9
+
10
+ key_name = ('key_for_' + name.to_s).to_sym
11
+ key = table_metadata[key_name]
12
+
13
+ unless key
14
+
15
+ msg = 'A key has not been defined at '+table_metadata[:name].to_s
16
+ raise SelectError.new(msg)
17
+
18
+ end
19
+
20
+ key
21
+
22
+ end
23
+
24
+ def get_relkind ( table )
25
+
26
+ table[:relkind].to_s.upcase!.gsub!('_', ' ')
27
+
28
+ end
29
+
30
+ def unroll_joins ( table_list, previous_table_metadata )
31
+
32
+ syntax = ''
33
+
34
+ # Array
35
+
36
+ table_list.each do |list|
37
+
38
+ for table_metadata, inner_table_list in list
39
+
40
+ rel = get_relkind table_metadata
41
+
42
+ syntax += ' ' + rel + ' ' + quote(table_metadata[:name]) + ' ON '
43
+
44
+ previous_key = get_key previous_table_metadata[:name], table_metadata
45
+ previous_id = quote(table_metadata[:name]) + '.' + previous_key
46
+
47
+ current_key = get_key table_metadata[:name], previous_table_metadata
48
+ current_id = quote(previous_table_metadata[:name]) + '.' + current_key
49
+
50
+ syntax += previous_id + ' = ' + current_id
51
+
52
+ next unless inner_table_list
53
+ next if inner_table_list.length == 0
54
+
55
+ syntax += unroll_joins inner_table_list, table_metadata
56
+
57
+ end
58
+
59
+ end
60
+
61
+ syntax
62
+
63
+ end
64
+
65
+ # Enable selection by column name.
66
+
67
+ def build_field_selection ( fields )
68
+
69
+ if fields
70
+
71
+ fields.join(',')
72
+
73
+ else
74
+
75
+ '*'
76
+
77
+ end
78
+
79
+ end
80
+
81
+ def sql_for_selecting ( options )
82
+
83
+ syntax = 'SELECT '
84
+ syntax += build_field_selection options[:fields]
85
+ syntax += ' FROM '
86
+
87
+ syntax += quote options[:joins] ? options[:joins][0].keys.first[:name] : options[:table_name]
88
+ syntax += unroll_joins options[:joins][0].values[0], options[:joins][0].keys.first if options[:joins]
89
+
90
+ syntax += parse_conditions options[:conditions]
91
+ syntax += parse_limit options[:limit]
92
+ syntax += parse_order options
93
+
94
+ syntax
95
+
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,55 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Sequence
5
+
6
+ private
7
+
8
+ # Generate SQL statement for creating a sequence.
9
+
10
+ def sql_for_creating_sequence ( options = {} )
11
+
12
+ syntax = 'CREATE SEQUENCE ' + quote(options[:sequence_name]) + ' '
13
+ syntax += 'START WITH ' + quote_value(options[:start_with]) + ' '
14
+ syntax += 'MINVALUE ' + quote_value(options[:min_value]) + ' '
15
+ syntax += 'MAXVALUE ' + quote_value(options[:max_value]) if options[:max_value]
16
+ syntax += 'INCREMENT BY ' + quote_value(options[:increment_by]) + ' '
17
+ syntax += options[:cycle] ? 'CYCLE ' : 'NO CYCLE '
18
+ syntax += 'CACHE ' + quote_value(options[:cache]) if options[:cache]
19
+
20
+ syntax
21
+
22
+ end
23
+
24
+ private
25
+
26
+ # Generate SQL statement for dropping a sequence.
27
+
28
+ def sql_for_dropping_sequence ( options = {} )
29
+
30
+ 'DROP SEQUENCE ' + quote(options[:sequence_name])
31
+
32
+ end
33
+
34
+ # Generate SQL statement for verifying sequences.
35
+ # Subclasses must override this method.
36
+
37
+ def sql_for_sequence_exists? ( options = {} )
38
+
39
+ raise FeatureNotFound
40
+
41
+ end
42
+
43
+ # Generate SQL statement for retrieving sequences.
44
+ # Subclasses must override this method.
45
+
46
+ def sql_for_retrieving_sequences
47
+
48
+ raise FeatureNotFound
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module TableMetadata
5
+
6
+ private
7
+
8
+ # There's no standard way to retrieve tables.
9
+ # Subclasses need to override this method.
10
+
11
+ def sql_for_retrieving_tables
12
+
13
+ raise FeatureNotFound
14
+
15
+ end
16
+
17
+ # There's no standard way to retrieve columns.
18
+ # Subclasses need to override this method.
19
+
20
+ def sql_for_retrieving_columns ( options = {} )
21
+
22
+ raise FeatureNotFound
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module TableOperation
5
+
6
+ private
7
+
8
+ # Generate SQL statement for dropping table.
9
+ # This will probably work for every database.
10
+
11
+ def sql_for_dropping_table ( options )
12
+
13
+ 'DROP TABLE ' + quote( options[:table_name] )
14
+
15
+ end
16
+
17
+ # Generate SQL statement for creating table.
18
+ # This will probably work for every database.
19
+
20
+ def sql_for_creating_table ( options )
21
+
22
+ columns = []
23
+ keys = []
24
+
25
+ # Let's parse some columns in order to provide default options.
26
+
27
+ parse_fields options[:fields] do |field|
28
+
29
+ # Convert a regular field into SQL's one.
30
+
31
+ columns << build_column( field )
32
+ keys << quote(field[:name]) if field[:pk]
33
+
34
+ end
35
+
36
+ syntax = 'CREATE TABLE ' + quote( options[:table_name] )
37
+ syntax += '('
38
+ syntax += columns.join(',')
39
+ syntax += ', PRIMARY KEY(' + keys.join(',') + ')' if keys.length > 0
40
+ syntax += ')'
41
+
42
+ syntax
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Transaction
5
+
6
+ private
7
+
8
+ # Generate SQL statement for initializing a transaction.
9
+
10
+ def sql_for_initializing_a_transaction
11
+
12
+ 'BEGIN'
13
+
14
+ end
15
+
16
+ # Generate SQL statement for terminating a transaction.
17
+
18
+ def sql_for_terminating_a_transaction
19
+
20
+ 'COMMIT'
21
+
22
+ end
23
+
24
+ # Generate SQL statement for rolling back a transaction.
25
+
26
+ def sql_for_rolling_back ( name = nil )
27
+
28
+ name == nil ? 'ROLLBACK' : 'ROLLBACK TO ' + name
29
+
30
+ end
31
+
32
+ # Generate SQL statement for placing a saving point.
33
+
34
+ def sql_for_saving_point ( name )
35
+
36
+ 'SAVEPOINT ' + name
37
+
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ module Imparcial
2
+ module Driver
3
+ module SQLBase
4
+ module Update
5
+
6
+ private
7
+
8
+ def sql_for_updating ( options )
9
+
10
+ syntax = 'UPDATE ' + quote(options[:table_name]) + ' SET '
11
+
12
+ options[:values].each do |name, value|
13
+
14
+ syntax += quote(name) + ' = ' + quote_value(value) + ','
15
+
16
+ end
17
+
18
+ syntax.chop!
19
+
20
+ syntax += parse_conditions options[:conditions]
21
+
22
+ syntax
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ require 'imparcial/driver/base/sql/table_operation'
2
+ require 'imparcial/driver/base/sql/table_metadata'
3
+ require 'imparcial/driver/base/sql/sequence'
4
+ require 'imparcial/driver/base/sql/transaction'
5
+ require 'imparcial/driver/base/sql/index'
6
+ require 'imparcial/driver/base/sql/insert'
7
+ require 'imparcial/driver/base/sql/delete'
8
+ require 'imparcial/driver/base/sql/select'
9
+ require 'imparcial/driver/base/sql/update'
10
+
11
+ module Imparcial
12
+ module Driver
13
+ module SQLBase
14
+ include TableOperation
15
+ include TableMetadata
16
+ include Sequence
17
+ include Transaction
18
+ include Index
19
+ include Insert
20
+ include Delete
21
+ include Select
22
+ include Update
23
+ end
24
+ end
25
+ end