dump_truck 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ class DumpTruck
2
+ module Mysql
3
+ class Translator
4
+ TABLE_NAME_REGEX = /^CREATE TABLE `(.*)`/
5
+ TABLE_FIELDS_REGEX = /^INSERT INTO `[^`]*` \((.*?)\)/
6
+ TABLE_VALUES_REGEX = /VALUES (.*);/
7
+ NUMBER = /-|\d/
8
+ INTEGER = /-?\d+/
9
+ FLOAT = /-?\d+\.\d+/
10
+ NON_QUOTE = /([^'\\]|\\.)*/
11
+
12
+ def table?(line)
13
+ line =~ TABLE_NAME_REGEX
14
+ end
15
+
16
+ def extract_table(line)
17
+ line.scan(TABLE_NAME_REGEX).flatten.first
18
+ end
19
+
20
+ def insert?(line)
21
+ line =~ TABLE_FIELDS_REGEX
22
+ end
23
+
24
+ def extract_insert(line)
25
+ fields = extract_fields(line)
26
+ [fields, extract_rows(line, fields)]
27
+ end
28
+
29
+ def generate_insert(table, keys, data)
30
+ "INSERT INTO `#{table}` (#{stringify_keys(keys)}) VALUES #{stringify_values(keys, data)};\n"
31
+ end
32
+
33
+ private
34
+
35
+ def extract_fields(line)
36
+ fields_string = line.scan(TABLE_FIELDS_REGEX).flatten.first
37
+ fields_string.split(', ').map{|field| field[1..-2]}
38
+ end
39
+
40
+ def extract_rows(line, fields)
41
+ values_string = line.scan(TABLE_VALUES_REGEX).flatten.first
42
+ data = extract_values(values_string, fields, line)
43
+ data.map{|values| Hash[fields.zip(values)]}
44
+ end
45
+
46
+ def extract_values(values_string, fields, line)
47
+ scanner = StringScanner.new(values_string)
48
+ data = []
49
+ values = []
50
+
51
+ until(scanner.eos?)
52
+ values << case scanner.peek(1)
53
+ when NUMBER
54
+ extract_number(scanner)
55
+ when "'"
56
+ extract_string(scanner)
57
+ when 'N'
58
+ extract_null(scanner)
59
+ when ')'
60
+ scanner.getch
61
+ data << values
62
+ values = []
63
+ next
64
+ when /[(, ]/
65
+ scanner.getch
66
+ next
67
+ else
68
+ context = scanner.pre_match[-60..-1] + scanner.peek(1) + scanner.rest[0..60]
69
+ raise "Unexpected character #{scanner.peek(1).inspect} at #{scanner.pos}. Last values: #{values.inspect}. Context: #{context.inspect}. Line: #{line.inspect}"
70
+ end
71
+ end
72
+
73
+ data
74
+ end
75
+
76
+ def extract_number(scanner)
77
+ if (number = scanner.scan(FLOAT))
78
+ number.to_f
79
+ else
80
+ scanner.scan(INTEGER).to_i
81
+ end
82
+ end
83
+
84
+ def extract_string(scanner)
85
+ scanner.getch
86
+ string = scanner.scan(NON_QUOTE)
87
+ scanner.getch
88
+
89
+ string
90
+ end
91
+
92
+ def extract_null(scanner)
93
+ scanner.scan(/NULL/)
94
+ nil
95
+ end
96
+
97
+ def stringify_keys(keys)
98
+ keys.map{|key| "`#{key}`"}.join(', ')
99
+ end
100
+
101
+ def stringify_values(keys, data)
102
+ data.map do |datum|
103
+ values = datum.values_at(*keys)
104
+ values_string = values.map{|value| stringify_field(value)}.join(',')
105
+ "(#{values_string})"
106
+ end.join(',')
107
+ end
108
+
109
+ def stringify_field(value)
110
+ case value
111
+ when nil
112
+ 'NULL'
113
+ when Numeric
114
+ value.to_s
115
+ when String
116
+ "'#{value}'"
117
+ else
118
+ raise "Unable to stringify #{value.inspect}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,55 @@
1
+ class DumpTruck
2
+ class SchemaConfiguration
3
+ attr_reader :name
4
+
5
+ def initialize(name)
6
+ @name = name
7
+ @tables = Hash.new(TableConfiguration.new{truncate})
8
+ @target_path = 'tmp'
9
+ @target_name_generator = proc{|schema| schema}
10
+
11
+ instance_eval(&Proc.new) if block_given?
12
+ end
13
+
14
+ def target_path(target_path = nil)
15
+ @target_path = target_path || @target_path
16
+ end
17
+
18
+ def target_name
19
+ @target_name_generator = Proc.new
20
+ end
21
+
22
+ def target
23
+ File.join(@target_path, @target_name_generator.call(@name) + '.sql.gz')
24
+ end
25
+
26
+ def table_default
27
+ if block_given?
28
+ @tables.default = TableConfiguration.new(&Proc.new)
29
+ else
30
+ @tables.default
31
+ end
32
+ end
33
+
34
+ def table(name, &block)
35
+ name = name.to_s
36
+ @tables[name] = TableConfiguration.new(name, &block)
37
+ end
38
+
39
+ def tables
40
+ @tables.values
41
+ end
42
+
43
+ def table_config_for(table)
44
+ @tables[table.to_s]
45
+ end
46
+
47
+ def ==(other)
48
+ name == other.name && target_path == other.target_path && tables == other.tables
49
+ end
50
+
51
+ def to_s
52
+ "<DumpTruck::SchemaConfiguration(#{name}) target:#{target} (#{tables.map(&:to_s).join(', ')})>"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,63 @@
1
+ class DumpTruck
2
+ class TableConfiguration
3
+ attr_reader :name, :mode, :query, :obfuscators
4
+
5
+ def initialize(name = nil)
6
+ @name = name.to_s
7
+ @obfuscators = Hash.new(proc{|value| value})
8
+ @mode = :none
9
+
10
+ instance_eval(&Proc.new) if block_given?
11
+ end
12
+
13
+ def truncate
14
+ @mode = :none
15
+ end
16
+
17
+ def ignore
18
+ @mode = :ignore
19
+ end
20
+
21
+ def keep(query = nil)
22
+ @query = query
23
+
24
+ if query
25
+ @mode = :some
26
+ else
27
+ @mode = :all
28
+ end
29
+ end
30
+
31
+ def obfuscate_default
32
+ if block_given?
33
+ @obfuscators.default = Proc.new
34
+ else
35
+ @obfuscators.default
36
+ end
37
+ end
38
+
39
+ def obfuscate(column)
40
+ column = column.to_s
41
+ if block_given?
42
+ @obfuscators[column] = Proc.new
43
+ else
44
+ @obfuscators[column] = proc{nil}
45
+ end
46
+ end
47
+
48
+ def obfuscate_value(column, value, n)
49
+ @obfuscators[column.to_s].call(value, n)
50
+ end
51
+
52
+ def ==(other)
53
+ name == other.name &&
54
+ mode == other.mode &&
55
+ (mode != :some || query == other.query)
56
+ end
57
+
58
+ def to_s
59
+ query_string = mode == :some ? ", query: #{query}" : ''
60
+ "<DumpTruck::TableConfiguration(#{name}) mode: #{mode}#{query_string} (#{obfuscators.keys.join(', ')})>"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ class DumpTruck
2
+ class Target
3
+ def initialize(target_file)
4
+ @target_file = target_file
5
+ end
6
+
7
+ def open
8
+ Zlib::GzipWriter.open(@target_file) do |target|
9
+ yield target
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,70 @@
1
+ require 'zlib'
2
+
3
+ class DumpTruck
4
+ class Truck
5
+ def initialize(schema_config, client, translator)
6
+ @schema_config = schema_config
7
+ @client = client
8
+ @translator = translator
9
+ end
10
+
11
+ def dump
12
+ tables = extract_tables
13
+ dump_schema(tables)
14
+ end
15
+
16
+ protected
17
+
18
+ attr_reader :schema_config, :client, :translator
19
+
20
+ def extract_tables
21
+ client.tables_dump do |io|
22
+ io.each.map do |line|
23
+ extract_table(line) if translator.table?(line)
24
+ end.compact
25
+ end
26
+ end
27
+
28
+ def dump_schema(tables)
29
+ Target.new(schema_config.target).open do |target|
30
+ tables.each do |table|
31
+ config = schema_config.table_config_for(table)
32
+
33
+ dump_data(config, table, target) unless config.mode == :ignore
34
+ end
35
+ end
36
+ end
37
+
38
+ def dump_data(config, table, target)
39
+ client.data_dump(config, table) do |io|
40
+ row_num = 0
41
+ io.each do |line|
42
+ line, row_num = translator.insert?(line) ? obfuscate(config, table, line, row_num) : [line, row_num]
43
+
44
+ target.write(line)
45
+ end
46
+ end
47
+ end
48
+
49
+ def obfuscate(config, table, line, row_num)
50
+ return '' if config.mode == :none
51
+
52
+ fields, data = extract_insert(line)
53
+
54
+ data = data.map do |datum|
55
+ row_num += 1
56
+ Hash[datum.map{|field, value| [field, config.obfuscate_value(field, value, row_num)]}]
57
+ end
58
+
59
+ [translator.generate_insert(table, fields, data), row_num]
60
+ end
61
+
62
+ def extract_table(line)
63
+ translator.extract_table(line)
64
+ end
65
+
66
+ def extract_insert(line)
67
+ translator.extract_insert(line)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ class DumpTruck
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe DumpTruck::Configuration do
4
+ describe '.new' do
5
+ context "when a configuration block is passed" do
6
+ let(:config) do
7
+ DumpTruck::Configuration.new do
8
+ database(:mysql){}
9
+ database(:postgres){}
10
+ end
11
+ end
12
+ subject{config}
13
+
14
+ its(:databases) do
15
+ should eq([
16
+ DumpTruck::DatabaseConfiguration.new(:mysql),
17
+ DumpTruck::DatabaseConfiguration.new(:postgres)
18
+ ])
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe DumpTruck::DatabaseConfiguration do
4
+ describe '.new' do
5
+ context "when a configuration block is passed" do
6
+ let(:config) do
7
+ DumpTruck::DatabaseConfiguration.new(:mysql) do
8
+ hostname 'localhost'
9
+ user 'root'
10
+ password 'secret'
11
+
12
+ schema('app_production'){}
13
+ schema('app_staging'){}
14
+ end
15
+ end
16
+ subject{config}
17
+
18
+ its(:hostname){should eq('localhost')}
19
+ its(:user){should eq('root')}
20
+ its(:password){should eq('secret')}
21
+ its(:schemas) do
22
+ should eq([
23
+ DumpTruck::SchemaConfiguration.new('app_production'),
24
+ DumpTruck::SchemaConfiguration.new('app_staging')
25
+ ])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe DumpTruck do
4
+ it 'should have a version number' do
5
+ expect(DumpTruck::VERSION).not_to be nil
6
+ end
7
+
8
+ describe '.new' do
9
+ context "when given the config for a database" do
10
+ let(:truck_config) do
11
+ DumpTruck.new do
12
+ database(:mysql){}
13
+ end.config
14
+ end
15
+ subject{truck_config}
16
+
17
+ its(:databases) do
18
+ should eq([DumpTruck::DatabaseConfiguration.new(:mysql)])
19
+ end
20
+ end
21
+ end
22
+
23
+ describe '#dump' do
24
+ let(:truck) do
25
+ DumpTruck.new do
26
+ database(:mysql) do
27
+ user 'root'
28
+ hostname 'localhost'
29
+
30
+ schema(:app_production) do
31
+ target_path(File.expand_path('../../tmp', __FILE__))
32
+
33
+ table(:roles){keep}
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,147 @@
1
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
2
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
3
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
4
+ /*!40101 SET NAMES utf8 */;
5
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
6
+ /*!40103 SET TIME_ZONE='+00:00' */;
7
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
8
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
9
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
10
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
11
+ DROP TABLE IF EXISTS `permissions`;
12
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
13
+ /*!40101 SET character_set_client = utf8 */;
14
+ CREATE TABLE `permissions` (
15
+ `id` int(11) NOT NULL AUTO_INCREMENT,
16
+ `name` varchar(255) NOT NULL,
17
+ `created_at` datetime DEFAULT NULL,
18
+ `updated_at` datetime DEFAULT NULL,
19
+ PRIMARY KEY (`id`),
20
+ UNIQUE KEY `index_permissions_on_name` (`name`)
21
+ ) ENGINE=InnoDB AUTO_INCREMENT=343 DEFAULT CHARSET=utf8;
22
+ /*!40101 SET character_set_client = @saved_cs_client */;
23
+
24
+ LOCK TABLES `permissions` WRITE;
25
+ /*!40000 ALTER TABLE `permissions` DISABLE KEYS */;
26
+ INSERT INTO `permissions` (`id`, `name`, `created_at`, `updated_at`) VALUES (12,'account:login','2009-08-11 11:10:17','2009-08-11 11:10:17'),(24,'job_artifacts:view','2009-08-11 11:10:17','2009-08-11 11:10:17'),(36,'charities:view','2009-08-11 11:10:17','2009-08-11 11:10:17'),(48,'charities:create','2009-08-11 11:10:17','2009-08-11 11:10:17'),(6,'charities:edit','2009-08-11 11:10:17','2009-08-11 11:10:17'),(61,'careers:create','2009-08-11 11:10:17','2009-08-11 11:10:17'),(68,'careers:view','2009-08-11 11:10:18','2009-08-11 11:10:18'),(90,'careers:edit','2009-08-11 11:10:18','2009-08-11 11:10:18'),(10,'media_stories:create','2009-08-11 11:10:18','2009-08-11 11:10:18'),(101,'media_stories:view','2009-08-11 11:10:18','2009-08-11 11:10:18'),(113,'media_stories:edit','2009-08-11 11:10:18','2009-08-11 11:10:18'),(123,'media_stories:destroy','2009-08-11 11:10:18','2009-08-11 11:10:18');
27
+ /*!40000 ALTER TABLE `permissions` ENABLE KEYS */;
28
+ UNLOCK TABLES;
29
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
30
+
31
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
32
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
33
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
34
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
35
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
36
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
37
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
38
+
39
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
40
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
41
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
42
+ /*!40101 SET NAMES utf8 */;
43
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
44
+ /*!40103 SET TIME_ZONE='+00:00' */;
45
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
46
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
47
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
48
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
49
+ DROP TABLE IF EXISTS `roles`;
50
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
51
+ /*!40101 SET character_set_client = utf8 */;
52
+ CREATE TABLE `roles` (
53
+ `id` int(11) NOT NULL AUTO_INCREMENT,
54
+ `name` varchar(255) NOT NULL,
55
+ `description` varchar(255) DEFAULT NULL,
56
+ `created_at` datetime DEFAULT NULL,
57
+ `updated_at` datetime DEFAULT NULL,
58
+ PRIMARY KEY (`id`),
59
+ UNIQUE KEY `index_roles_on_name` (`name`)
60
+ ) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8;
61
+ /*!40101 SET character_set_client = @saved_cs_client */;
62
+
63
+ LOCK TABLES `roles` WRITE;
64
+ /*!40000 ALTER TABLE `roles` DISABLE KEYS */;
65
+ INSERT INTO `roles` (`id`, `name`, `description`, `created_at`, `updated_at`) VALUES (21,'1',NULL,'2009-08-11 11:10:17','2009-08-11 11:10:17'),(23,'2',NULL,'2009-08-11 11:10:17','2009-08-11 11:10:17'),(34,'3',NULL,'2009-08-11 11:10:17','2009-08-11 11:10:17'),(84,'4',NULL,'2009-08-11 11:10:18','2009-08-11 11:10:18'),(85,'5',NULL,'2009-08-11 11:10:18','2009-08-11 11:10:18'),(96,'6',NULL,'2009-08-11 11:10:18','2009-08-11 11:10:18'),(207,'7',NULL,'2009-08-11 11:10:18','2009-08-11 11:10:18'),(308,'8',NULL,'2009-08-11 11:10:18','2009-08-11 11:10:18');
66
+ /*!40000 ALTER TABLE `roles` ENABLE KEYS */;
67
+ UNLOCK TABLES;
68
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
69
+
70
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
71
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
72
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
73
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
74
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
75
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
76
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
77
+
78
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
79
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
80
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
81
+ /*!40101 SET NAMES utf8 */;
82
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
83
+ /*!40103 SET TIME_ZONE='+00:00' */;
84
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
85
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
86
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
87
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
88
+ DROP TABLE IF EXISTS `users`;
89
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
90
+ /*!40101 SET character_set_client = utf8 */;
91
+ CREATE TABLE `users` (
92
+ `id` int(11) NOT NULL AUTO_INCREMENT,
93
+ `login` varchar(255) CHARACTER SET utf8 NOT NULL,
94
+ `email` varchar(255) CHARACTER SET utf8 NOT NULL,
95
+ `encrypted_password` varchar(128) NOT NULL DEFAULT '',
96
+ `password_salt` varchar(128) NOT NULL DEFAULT '',
97
+ `created_at` datetime DEFAULT NULL,
98
+ `updated_at` datetime DEFAULT NULL,
99
+ `remember_token` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
100
+ `remember_token_expires_at` datetime DEFAULT NULL,
101
+ `confirmed_agreement` tinyint(1) NOT NULL DEFAULT '0',
102
+ `first_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
103
+ `middle_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
104
+ `last_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
105
+ `role` int(11) DEFAULT '0',
106
+ `status` int(11) DEFAULT '0',
107
+ `pw_reset_code` varchar(40) CHARACTER SET utf8 DEFAULT NULL,
108
+ `activated` tinyint(1) DEFAULT '0',
109
+ `activation_key` varchar(40) DEFAULT NULL,
110
+ `telephone` varchar(255) DEFAULT NULL,
111
+ `confirmed_referral_terms` tinyint(1) DEFAULT '0',
112
+ `confirmed_referral_terms_at` datetime DEFAULT NULL,
113
+ `current_facility_id` int(11) DEFAULT NULL,
114
+ `selected_drive_id` int(11) DEFAULT NULL,
115
+ `triggers_qc` tinyint(1) NOT NULL DEFAULT '0',
116
+ `persistence_token` varchar(255) DEFAULT NULL,
117
+ `single_access_token` varchar(255) DEFAULT NULL,
118
+ `requires_ldap_authentication` tinyint(1) DEFAULT '0',
119
+ `sign_in_count` int(11) DEFAULT '0',
120
+ `current_sign_in_at` datetime DEFAULT NULL,
121
+ `last_sign_in_at` datetime DEFAULT NULL,
122
+ `current_sign_in_ip` varchar(255) DEFAULT NULL,
123
+ `last_sign_in_ip` varchar(255) DEFAULT NULL,
124
+ PRIMARY KEY (`id`),
125
+ UNIQUE KEY `index_users_on_email` (`email`),
126
+ UNIQUE KEY `index_users_on_single_access_token` (`single_access_token`),
127
+ UNIQUE KEY `index_users_on_pw_reset_code` (`pw_reset_code`),
128
+ KEY `index_users_on_activation_key` (`activation_key`),
129
+ KEY `index_users_on_activated` (`activated`),
130
+ KEY `index_users_on_last_name` (`last_name`)
131
+ ) ENGINE=InnoDB AUTO_INCREMENT=919492 DEFAULT CHARSET=latin1;
132
+ /*!40101 SET character_set_client = @saved_cs_client */;
133
+
134
+ LOCK TABLES `users` WRITE;
135
+ /*!40000 ALTER TABLE `users` DISABLE KEYS */;
136
+ /*!40000 ALTER TABLE `users` ENABLE KEYS */;
137
+ UNLOCK TABLES;
138
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
139
+
140
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
141
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
142
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
143
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
144
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
145
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
146
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
147
+