dump_truck 0.0.2

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.
@@ -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
+