purview 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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