purview 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -114,6 +114,10 @@ module Purview
114
114
  ]
115
115
  end
116
116
 
117
+ def limit_map
118
+ super.merge(Purview::Types::String => 255)
119
+ end
120
+
117
121
  def limitless_types
118
122
  super + [
119
123
  Purview::Types::Money,
@@ -0,0 +1,173 @@
1
+ module Purview
2
+ module Databases
3
+ class SQLite < Base
4
+ private
5
+
6
+ def connection_type
7
+ Purview::Connections::SQLite
8
+ end
9
+
10
+ def create_index_sql(table_name, index_name, index, index_opts={})
11
+ 'CREATE%sINDEX %s ON %s (%s)' % [
12
+ index.unique? ? ' UNIQUE ' : ' ',
13
+ index_name,
14
+ table_name,
15
+ column_names(index).join(', '),
16
+ ]
17
+ end
18
+
19
+ def create_table_sql(table_name, table, table_opts={})
20
+ 'CREATE TABLE %s (%s)' % [
21
+ table_name,
22
+ column_definitions(table).join(', '),
23
+ ]
24
+ end
25
+
26
+ def create_temporary_table_sql(table_name, table, table_opts={})
27
+ 'CREATE TEMPORARY TABLE %s (%s)' % [
28
+ table_name,
29
+ column_definitions(table).join(', '),
30
+ ]
31
+ end
32
+
33
+ def dialect_type
34
+ Purview::Dialects::SQLite
35
+ end
36
+
37
+ def disable_table_sql(table)
38
+ 'UPDATE %s SET %s = %s WHERE %s = %s AND %s IS NOT NULL' % [
39
+ table_metadata_table.name,
40
+ table_metadata_table.enabled_at_column.name,
41
+ null_value,
42
+ table_metadata_table.table_name_column.name,
43
+ quoted(table.name),
44
+ table_metadata_table.enabled_at_column.name,
45
+ ]
46
+ end
47
+
48
+ def drop_index_sql(table_name, index_name, index, index_opts={})
49
+ 'DROP INDEX %s' % [
50
+ index_name,
51
+ ]
52
+ end
53
+
54
+ def drop_table_sql(table_name, table, table_opts={})
55
+ 'DROP TABLE %s' % [
56
+ table_name,
57
+ ]
58
+ end
59
+
60
+ def enable_table_sql(table, timestamp)
61
+ 'UPDATE %s SET %s = %s WHERE %s = %s AND %s IS NULL' % [
62
+ table_metadata_table.name,
63
+ table_metadata_table.enabled_at_column.name,
64
+ quoted(timestamp),
65
+ table_metadata_table.table_name_column.name,
66
+ quoted(table.name),
67
+ table_metadata_table.enabled_at_column.name,
68
+ ]
69
+ end
70
+
71
+ def ensure_table_metadata_absent_for_table_sql(table)
72
+ 'DELETE FROM %s WHERE %s = %s' % [
73
+ table_metadata_table.name,
74
+ table_metadata_table.table_name_column.name,
75
+ quoted(table.name),
76
+ ]
77
+ end
78
+
79
+ def ensure_table_metadata_exists_for_table_sql(table)
80
+ 'INSERT INTO %s (%s) SELECT %s WHERE NOT EXISTS (SELECT 1 FROM %s WHERE %s = %s)' % [
81
+ table_metadata_table.name,
82
+ table_metadata_table.table_name_column.name,
83
+ quoted(table.name),
84
+ table_metadata_table.name,
85
+ table_metadata_table.table_name_column.name,
86
+ quoted(table.name),
87
+ ]
88
+ end
89
+
90
+ def ensure_table_metadata_table_exists_sql
91
+ 'CREATE TABLE IF NOT EXISTS %s (%s)' % [
92
+ table_metadata_table.name,
93
+ column_definitions(table_metadata_table).join(', '),
94
+ ]
95
+ end
96
+
97
+ def initialize_table_sql(table, timestamp)
98
+ 'UPDATE %s SET %s = %s WHERE %s = %s AND %s IS NULL' % [
99
+ table_metadata_table.name,
100
+ table_metadata_table.max_timestamp_pulled_column.name,
101
+ quoted(timestamp),
102
+ table_metadata_table.table_name_column.name,
103
+ quoted(table.name),
104
+ table_metadata_table.max_timestamp_pulled_column.name,
105
+ ]
106
+ end
107
+
108
+ def get_table_metadata_value_sql(table, column)
109
+ 'SELECT %s FROM %s WHERE %s = %s' % [
110
+ column.name,
111
+ table_metadata_table.name,
112
+ table_metadata_table.table_name_column.name,
113
+ quoted(table.name),
114
+ ]
115
+ end
116
+
117
+ def limit_map
118
+ super.merge(Purview::Types::String => 255)
119
+ end
120
+
121
+ def lock_table_sql(table, timestamp)
122
+ 'UPDATE %s SET %s = %s WHERE %s = %s AND %s IS NULL' % [
123
+ table_metadata_table.name,
124
+ table_metadata_table.locked_at_column.name,
125
+ quoted(timestamp),
126
+ table_metadata_table.table_name_column.name,
127
+ quoted(table.name),
128
+ table_metadata_table.locked_at_column.name,
129
+ ]
130
+ end
131
+
132
+ def next_table_sql(timestamp)
133
+ 'SELECT %s FROM %s WHERE %s IS NOT NULL AND %s IS NOT NULL AND %s IS NULL ORDER BY %s IS NULL DESC, %s LIMIT 1' % [
134
+ table_metadata_table.table_name_column.name,
135
+ table_metadata_table.name,
136
+ table_metadata_table.enabled_at_column.name,
137
+ table_metadata_table.max_timestamp_pulled_column.name,
138
+ table_metadata_table.locked_at_column.name,
139
+ table_metadata_table.last_pulled_at_column.name,
140
+ table_metadata_table.last_pulled_at_column.name,
141
+ ]
142
+ end
143
+
144
+ def set_table_metadata_value_sql(table, column, value)
145
+ 'UPDATE %s SET %s = %s WHERE %s = %s' % [
146
+ table_metadata_table.name,
147
+ column.name,
148
+ quoted(value),
149
+ table_metadata_table.table_name_column.name,
150
+ quoted(table.name),
151
+ ]
152
+ end
153
+
154
+ def type_map
155
+ super.merge(
156
+ Purview::Types::Money => 'decimal',
157
+ Purview::Types::UUID => 'varchar',
158
+ )
159
+ end
160
+
161
+ def unlock_table_sql(table)
162
+ 'UPDATE %s SET %s = %s WHERE %s = %s AND %s IS NOT NULL' % [
163
+ table_metadata_table.name,
164
+ table_metadata_table.locked_at_column.name,
165
+ null_value,
166
+ table_metadata_table.table_name_column.name,
167
+ quoted(table.name),
168
+ table_metadata_table.locked_at_column.name,
169
+ ]
170
+ end
171
+ end
172
+ end
173
+ end
@@ -3,3 +3,4 @@ require 'purview/dialects/base'
3
3
  require 'purview/dialects/mssql'
4
4
  require 'purview/dialects/mysql'
5
5
  require 'purview/dialects/postgresql'
6
+ require 'purview/dialects/sqlite'
@@ -0,0 +1,25 @@
1
+ module Purview
2
+ module Dialects
3
+ class SQLite < Base
4
+ def false_value
5
+ '0'
6
+ end
7
+
8
+ def null_value
9
+ 'NULL'
10
+ end
11
+
12
+ def quoted(value)
13
+ value.nil? ? null_value : value.quoted
14
+ end
15
+
16
+ def sanitized(value)
17
+ value.nil? ? null_value : value.sanitized
18
+ end
19
+
20
+ def true_value
21
+ '1'
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,4 +1,6 @@
1
1
  require 'purview/loaders/base'
2
2
 
3
+ require 'purview/loaders/mssql'
3
4
  require 'purview/loaders/mysql'
4
5
  require 'purview/loaders/postgresql'
6
+ require 'purview/loaders/sqlite'
@@ -0,0 +1,85 @@
1
+ module Purview
2
+ module Loaders
3
+ class MSSQL < Base
4
+ private
5
+
6
+ def dialect_type
7
+ Purview::Dialects::MSSQL
8
+ end
9
+
10
+ def id_in_sql(temporary_table_name)
11
+ 'SELECT %s FROM %s' % [
12
+ table.id_column.name,
13
+ temporary_table_name,
14
+ ]
15
+ end
16
+
17
+ def in_window_sql(window)
18
+ '%s BETWEEN %s AND %s' % [
19
+ table.updated_timestamp_column.name,
20
+ quoted(window.min),
21
+ quoted(window.max),
22
+ ]
23
+ end
24
+
25
+ def not_in_window_sql(window)
26
+ '%s NOT BETWEEN %s AND %s' % [
27
+ table.updated_timestamp_column.name,
28
+ quoted(window.min),
29
+ quoted(window.max),
30
+ ]
31
+ end
32
+
33
+ def table_delete_sql(window, temporary_table_name)
34
+ 'DELETE FROM %s WHERE %s AND %s NOT IN (%s)' % [
35
+ table.name,
36
+ in_window_sql(window),
37
+ table.id_column.name,
38
+ id_in_sql(temporary_table_name),
39
+ ]
40
+ end
41
+
42
+ def table_insert_sql(window, temporary_table_name)
43
+ 'INSERT INTO %s (%s) SELECT %s FROM %s t1 WHERE NOT EXISTS (SELECT 1 FROM %s t2 WHERE t1.%s = t2.%s)' % [
44
+ table.name,
45
+ table.column_names.join(', '),
46
+ table.column_names.join(', '),
47
+ temporary_table_name,
48
+ table.name,
49
+ table.id_column.name,
50
+ table.id_column.name,
51
+ ]
52
+ end
53
+
54
+ def table_update_sql(window, temporary_table_name)
55
+ 'UPDATE %s t1 JOIN %s t2 ON t1.%s = t2.%s SET %s' % [
56
+ table.name,
57
+ temporary_table_name,
58
+ table.id_column.name,
59
+ table.id_column.name,
60
+ table.column_names.map { |column_name| "t1.#{column_name} = t2.#{column_name}" }.join(', '),
61
+ ]
62
+ end
63
+
64
+ def temporary_table_insert_sql(temporary_table_name, rows)
65
+ 'INSERT INTO %s (%s) VALUES %s' % [
66
+ temporary_table_name,
67
+ table.column_names.join(', '),
68
+ rows.map { |row| "(#{row_values(row)})" }.join(', ')
69
+ ]
70
+ end
71
+
72
+ def temporary_table_opts
73
+ super.merge(:create_indices => false)
74
+ end
75
+
76
+ def temporary_table_verify_sql(temporary_table_name, rows, window)
77
+ 'SELECT COUNT(1) %s FROM %s WHERE %s' % [
78
+ count_column_name,
79
+ temporary_table_name,
80
+ not_in_window_sql(window),
81
+ ]
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,85 @@
1
+ module Purview
2
+ module Loaders
3
+ class SQLite < Base
4
+ private
5
+
6
+ def dialect_type
7
+ Purview::Dialects::SQLite
8
+ end
9
+
10
+ def id_in_sql(temporary_table_name)
11
+ 'SELECT %s FROM %s' % [
12
+ table.id_column.name,
13
+ temporary_table_name,
14
+ ]
15
+ end
16
+
17
+ def in_window_sql(window)
18
+ '%s BETWEEN %s AND %s' % [
19
+ table.updated_timestamp_column.name,
20
+ quoted(window.min),
21
+ quoted(window.max),
22
+ ]
23
+ end
24
+
25
+ def not_in_window_sql(window)
26
+ '%s NOT BETWEEN %s AND %s' % [
27
+ table.updated_timestamp_column.name,
28
+ quoted(window.min),
29
+ quoted(window.max),
30
+ ]
31
+ end
32
+
33
+ def table_delete_sql(window, temporary_table_name)
34
+ 'DELETE FROM %s WHERE %s AND %s NOT IN (%s)' % [
35
+ table.name,
36
+ in_window_sql(window),
37
+ table.id_column.name,
38
+ id_in_sql(temporary_table_name),
39
+ ]
40
+ end
41
+
42
+ def table_insert_sql(window, temporary_table_name)
43
+ 'INSERT INTO %s (%s) SELECT %s FROM %s t1 WHERE NOT EXISTS (SELECT 1 FROM %s t2 WHERE t1.%s = t2.%s)' % [
44
+ table.name,
45
+ table.column_names.join(', '),
46
+ table.column_names.join(', '),
47
+ temporary_table_name,
48
+ table.name,
49
+ table.id_column.name,
50
+ table.id_column.name,
51
+ ]
52
+ end
53
+
54
+ def table_update_sql(window, temporary_table_name)
55
+ 'UPDATE %s t1 JOIN %s t2 ON t1.%s = t2.%s SET %s' % [
56
+ table.name,
57
+ temporary_table_name,
58
+ table.id_column.name,
59
+ table.id_column.name,
60
+ table.column_names.map { |column_name| "t1.#{column_name} = t2.#{column_name}" }.join(', '),
61
+ ]
62
+ end
63
+
64
+ def temporary_table_insert_sql(temporary_table_name, rows)
65
+ 'INSERT INTO %s (%s) VALUES %s' % [
66
+ temporary_table_name,
67
+ table.column_names.join(', '),
68
+ rows.map { |row| "(#{row_values(row)})" }.join(', ')
69
+ ]
70
+ end
71
+
72
+ def temporary_table_opts
73
+ super.merge(:create_indices => false)
74
+ end
75
+
76
+ def temporary_table_verify_sql(temporary_table_name, rows, window)
77
+ 'SELECT COUNT(1) %s FROM %s WHERE %s' % [
78
+ count_column_name,
79
+ temporary_table_name,
80
+ not_in_window_sql(window),
81
+ ]
82
+ end
83
+ end
84
+ end
85
+ end
@@ -4,4 +4,5 @@ require 'purview/pullers/base_sql'
4
4
  require 'purview/pullers/mssql'
5
5
  require 'purview/pullers/mysql'
6
6
  require 'purview/pullers/postgresql'
7
+ require 'purview/pullers/sqlite'
7
8
  require 'purview/pullers/uri'
@@ -0,0 +1,15 @@
1
+ module Purview
2
+ module Pullers
3
+ class SQLite < BaseSQL
4
+ private
5
+
6
+ def connection_type
7
+ Purview::Connections::SQLite
8
+ end
9
+
10
+ def dialect_type
11
+ Purview::Dialects::SQLite
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,14 +4,17 @@ require 'purview/raw_connections/jdbc/base'
4
4
  require 'purview/raw_connections/jdbc/jtds'
5
5
  require 'purview/raw_connections/jdbc/mysql'
6
6
  require 'purview/raw_connections/jdbc/postgres'
7
+ require 'purview/raw_connections/jdbc/sqlite3'
7
8
 
8
9
  require 'purview/raw_connections/mysql2'
9
10
  require 'purview/raw_connections/pg'
11
+ require 'purview/raw_connections/sqlite3'
10
12
  require 'purview/raw_connections/tiny_tds'
11
13
 
12
14
  if \
13
15
  !defined?(Purview::RawConnections::MSSQL) &&
14
16
  !defined?(Purview::RawConnections::MySQL) &&
15
- !defined?(Purview::RawConnections::PostgreSQL)
16
- raise 'Could not initialize raw-connections; please install and require one or more of the following gems: `jdbc-jtds`, `jdbc-mysql`, `jdbc-postgres`, `mysql2`, `pg` and/or `tiny_tds`'
17
+ !defined?(Purview::RawConnections::PostgreSQL) &&
18
+ !defined?(Purview::RawConnections::SQLite)
19
+ raise 'Could not initialize raw-connections; please install and require one or more of the following gems: `jdbc-jtds`, `jdbc-mysql`, `jdbc-postgres`, `jdbc-sqlite3`, `mysql2`, `pg`, `sqlite3` and/or `tiny_tds`'
17
20
  end
@@ -1,4 +1,4 @@
1
- safe_require('jdbc-mysql')
1
+ safe_require('jdbc/mysql')
2
2
 
3
3
  if defined?(Jdbc::MySQL)
4
4
  Jdbc::MySQL.load_driver