mysqlaudit 0.0.1
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.
- checksums.yaml +15 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/bin/mysqlaudit +58 -0
- data/lib/mysqlaudit/actions.rb +62 -0
- data/lib/mysqlaudit/audit.rb +168 -0
- data/lib/mysqlaudit/version.rb +3 -0
- data/lib/mysqlaudit.rb +7 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MjRmYmMyZjFiYjNiMGNkYzllNTY3NjZjMWJlZTljNjY0MTUwOTE1Zg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2MwYTg0NWFlZjQ5NzAyMTQzYWRmYzc0YWEwMDk4NGRmY2ViN2ZjNw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODUzYWIxYWYxY2NhMTI2MTlmZTM0NzhmN2MyYTEyYWY0MjlhMzEwMGUxNWZh
|
10
|
+
MjVhMmI3ZDQ1YWVlZTE0YjRjM2E3MTJlZGQxMGFiYjA2YjA4NWQ1NWQyOWIz
|
11
|
+
NzQ1MDVmYmM5NWYzNWFkYzEzYWI0YTA1ZjQ5NjhlMDMxYTliNzU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjI4ODI0MWQwODYyNWViZjdiMjFiYWIwZmM0ZmUyOWY2NzVkN2RkYjMyNzYx
|
14
|
+
OWZkNTc5NzNiZGFkYWNlYjNkMGJhMjlhMzgwYWFlZTk5NjRjYjI4Nzg5MWU5
|
15
|
+
NGY2N2EyYjc0ZTBkNDFlOWEzZWZkZTBkY2M2YzlhMDJiMWY0MzQ=
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Nicola Strappazzon C.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# Mysqlaudit
|
2
|
+
|
3
|
+
MySQL tool build in ruby for audit all tables with triggers, this is a change
|
4
|
+
log for SQL transactions executed sentences as INSERT, UPDATE, and DELETE.
|
5
|
+
|
6
|
+
## Useful for:
|
7
|
+
|
8
|
+
1. Log all changes on table.
|
9
|
+
2. Rollback changes.
|
10
|
+
3. Detecting unnecessary transactions.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Install this tool executing the following command:
|
15
|
+
|
16
|
+
```Shell
|
17
|
+
$ gem install mysqlaudit
|
18
|
+
```
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
This is a simple tutorial to understand this tool, please, follow next
|
23
|
+
instructions:
|
24
|
+
|
25
|
+
### Install test enviroment
|
26
|
+
|
27
|
+
Create test database and table:
|
28
|
+
|
29
|
+
```SQL
|
30
|
+
CREATE DATABASE audit CHARACTER SET utf8;
|
31
|
+
|
32
|
+
USE audit;
|
33
|
+
|
34
|
+
CREATE TABLE foo (
|
35
|
+
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
36
|
+
email char(255) NOT NULL,
|
37
|
+
name VARCHAR(45) NOT NULL,
|
38
|
+
birthday TIMESTAMP NOT NULL,
|
39
|
+
PRIMARY KEY (id),
|
40
|
+
UNIQUE KEY id_UNIQUE (id)
|
41
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
42
|
+
```
|
43
|
+
|
44
|
+
Install audit table and triggers on foo table:
|
45
|
+
|
46
|
+
```Shell
|
47
|
+
$ mysqlaudit install --host 127.0.0.1 --user root --pass admin --schema audit --table foo
|
48
|
+
```
|
49
|
+
|
50
|
+
The following query catch all changes of data with trigger audit:
|
51
|
+
|
52
|
+
```SQL
|
53
|
+
INSERT INTO foo (email, name, birthday) VALUES ('abc@abc.com','Fulano','1980-04-01');
|
54
|
+
INSERT INTO foo (email, name, birthday) VALUES ('def@def.org','Mengano','1979-03-28');
|
55
|
+
INSERT INTO foo (email, name, birthday) VALUES ('ghi@ghi.net','Jaimito','1980-06-15');
|
56
|
+
UPDATE foo SET name = 'Zutano' WHERE id = 3;
|
57
|
+
DELETE FROM foo WHERE id = 2;
|
58
|
+
```
|
59
|
+
|
60
|
+
To apply rollback with specific transaction, this generate SQL output:
|
61
|
+
|
62
|
+
### Get deleted data:
|
63
|
+
|
64
|
+
```Shell
|
65
|
+
$ mysqlaudit rollback --host 127.0.0.1 \
|
66
|
+
--user root \
|
67
|
+
--pass admin \
|
68
|
+
--schema audit \
|
69
|
+
--table foo \
|
70
|
+
--statement delete
|
71
|
+
```
|
72
|
+
|
73
|
+
Output of last executed command:
|
74
|
+
|
75
|
+
```
|
76
|
+
/* 2013-07-11 07:25:25 */ INSERT INTO foo (id, email, name, birthday) VALUES (2, 'def@def.org', 'Mengano', '1979-03-28 00:00:00');
|
77
|
+
```
|
78
|
+
|
79
|
+
### Get updated data:
|
80
|
+
```Shell
|
81
|
+
$ mysqlaudit rollback --host 127.0.0.1 \
|
82
|
+
--user root \
|
83
|
+
--pass admin \
|
84
|
+
--schema audit \
|
85
|
+
--table foo \
|
86
|
+
--statement update
|
87
|
+
```
|
88
|
+
|
89
|
+
Output of last executed command:
|
90
|
+
|
91
|
+
```
|
92
|
+
/* 2013-07-11 07:26:26 */ UPDATE users SET birthday = '1980-06-15 00:00:00' WHERE id = 3;
|
93
|
+
/* 2013-07-11 07:26:26 */ UPDATE users SET name = 'Jaimito' WHERE id = 3;
|
94
|
+
```
|
95
|
+
|
96
|
+
### Get inserted data:
|
97
|
+
```Shell
|
98
|
+
$ mysqlaudit rollback --host 127.0.0.1 \
|
99
|
+
--user root \
|
100
|
+
--pass admin \
|
101
|
+
--schema audit \
|
102
|
+
--table foo \
|
103
|
+
--statement insert
|
104
|
+
```
|
105
|
+
|
106
|
+
Output of last executed command:
|
107
|
+
|
108
|
+
```
|
109
|
+
/* 2013-07-11 07:27:27 */ DELETE FROM foo WHERE id = 1;
|
110
|
+
/* 2013-07-11 07:27:27 */ DELETE FROM foo WHERE id = 2;
|
111
|
+
/* 2013-07-11 07:27:27 */ DELETE FROM foo WHERE id = 3;
|
112
|
+
```
|
113
|
+
|
114
|
+
### Uninstall test enviroment:
|
115
|
+
|
116
|
+
Uninstall all triggers and drop audit table.
|
117
|
+
|
118
|
+
```Shell
|
119
|
+
$ mysqlaudit uninstall --host 127.0.0.1 \
|
120
|
+
--user root \
|
121
|
+
--pass admin \
|
122
|
+
--schema audit \
|
123
|
+
--table foo \
|
124
|
+
--drop-audit-table
|
125
|
+
```
|
126
|
+
|
127
|
+
Drop testing table and database:
|
128
|
+
|
129
|
+
```SQL
|
130
|
+
DROP TABLE audit;
|
131
|
+
DROP DATABASE foo;
|
132
|
+
```
|
133
|
+
|
134
|
+
For more information:
|
135
|
+
|
136
|
+
```Shell
|
137
|
+
$ mysqlaudit --help
|
138
|
+
```
|
139
|
+
|
140
|
+
## Warning
|
141
|
+
|
142
|
+
1. Do not use this tool in production before testing it.
|
143
|
+
2. Please, use when do you need.
|
144
|
+
3. The author is NOT responsible for misuse use of this tool.
|
145
|
+
|
146
|
+
## Contributing
|
147
|
+
|
148
|
+
1. Fork it
|
149
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
150
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
151
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
152
|
+
5. Create new Pull Request
|
data/bin/mysqlaudit
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Only for deploy this script.
|
4
|
+
$LOAD_PATH << './lib'
|
5
|
+
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'commander'
|
9
|
+
require 'commander/import'
|
10
|
+
require 'mysqlaudit'
|
11
|
+
require 'mysqlaudit/actions'
|
12
|
+
require 'mysqlaudit/version'
|
13
|
+
|
14
|
+
program :name, 'MySQL Audit Tool'
|
15
|
+
program :version, Mysqlaudit::VERSION
|
16
|
+
program :description, 'MySQL tool for audit all tables with triggers.'
|
17
|
+
program :help, 'Author', 'Nicola Strappazzon <nicola51980@gmail.com>'
|
18
|
+
|
19
|
+
command :install do |c|
|
20
|
+
c.description = 'Install audit table'
|
21
|
+
c.syntax = 'audits install --host 127.0.0.1 --user root [--pass admin] --schema sakila [--table foo]'
|
22
|
+
c.option '--host STRING', String, 'Host'
|
23
|
+
c.option '--user STRING', String, 'User'
|
24
|
+
c.option '--pass STRING', String, 'Password'
|
25
|
+
c.option '--schema STRING', String, 'Schema name'
|
26
|
+
c.option '--table STRING', String, 'Table name'
|
27
|
+
c.action do |args, options|
|
28
|
+
Mysqlaudit::Actions.new(options.host, options.user, options.pass, options.schema, options.table).install
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
command :uninstall do |c|
|
33
|
+
c.description = 'Uninstall audit table'
|
34
|
+
c.syntax = 'audits uninstall --host 127.0.0.1 --user root [--pass admin] --schema sakila [--table foo] [--[no-]drop-audit-table]'
|
35
|
+
c.option '--host STRING', String, 'Host'
|
36
|
+
c.option '--user STRING', String, 'User'
|
37
|
+
c.option '--pass STRING', String, 'Password'
|
38
|
+
c.option '--schema STRING', String, 'Schema name'
|
39
|
+
c.option '--table STRING', String, 'Table name'
|
40
|
+
c.option '--[no-]drop-audit-table', 'Drop audit table'
|
41
|
+
c.action do |args, options|
|
42
|
+
Mysqlaudit::Actions.new(options.host, options.user, options.pass, options.schema, options.table, options.drop_audit_table).uninstall
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
command :rollback do |c|
|
47
|
+
c.description = 'Rollback transaction cath in audit table'
|
48
|
+
c.syntax = 'audits rollback --host 127.0.0.1 --user root [--pass admin] --schema sakila --table foo --statement INSERT'
|
49
|
+
c.option '--host STRING', String, 'Host'
|
50
|
+
c.option '--user STRING', String, 'User'
|
51
|
+
c.option '--pass STRING', String, 'Password'
|
52
|
+
c.option '--schema STRING', String, 'Schema name'
|
53
|
+
c.option '--table STRING', String, 'Table name'
|
54
|
+
c.option '--statement STRING', String, 'Statement operation, INSERT, UPDATE, or DELETE'
|
55
|
+
c.action do |args, options|
|
56
|
+
Mysqlaudit::Actions.new(options.host, options.user, options.pass, options.schema, options.table, nil, options.statement).rollback
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'mysqlaudit/audit'
|
2
|
+
|
3
|
+
module Mysqlaudit
|
4
|
+
class Actions
|
5
|
+
@audit = nil
|
6
|
+
|
7
|
+
def initialize(host, user, password, schema, table, drop = nil, statement = nil)
|
8
|
+
# def initialize(schema, table, options = {})
|
9
|
+
# options = {host: 'localhost', user: 'root', password: ''}.merge(options)
|
10
|
+
|
11
|
+
$host = host
|
12
|
+
$user = user
|
13
|
+
$password = password
|
14
|
+
$schema = schema
|
15
|
+
$table = table
|
16
|
+
$drop = drop
|
17
|
+
$statement = statement
|
18
|
+
|
19
|
+
@audit = Mysqlaudit::Audit.new($host, $user, $password, $schema)
|
20
|
+
end
|
21
|
+
|
22
|
+
def install()
|
23
|
+
@audit.create_table()
|
24
|
+
|
25
|
+
if !$table
|
26
|
+
tables = @audit.get_tables()
|
27
|
+
tables.each do | table |
|
28
|
+
@audit.create_trigger(table, :insert)
|
29
|
+
@audit.create_trigger(table, :update)
|
30
|
+
@audit.create_trigger(table, :delete)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@audit.create_trigger($table, :insert)
|
34
|
+
@audit.create_trigger($table, :update)
|
35
|
+
@audit.create_trigger($table, :delete)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def uninstall()
|
40
|
+
if !$table
|
41
|
+
tables = @audit.get_tables()
|
42
|
+
tables.each do | table |
|
43
|
+
@audit.drop_trigger(table, :insert)
|
44
|
+
@audit.drop_trigger(table, :update)
|
45
|
+
@audit.drop_trigger(table, :delete)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
@audit.drop_trigger($table, :insert)
|
49
|
+
@audit.drop_trigger($table, :update)
|
50
|
+
@audit.drop_trigger($table, :delete)
|
51
|
+
end
|
52
|
+
|
53
|
+
if $drop
|
54
|
+
@audit.drop_table()
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def rollback()
|
59
|
+
@audit.rollback($table, $statement.to_sym)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mysql2'
|
3
|
+
|
4
|
+
# @todo Optimize passing params on methods with maps.
|
5
|
+
# @todo Optimize is set params to execute methods.
|
6
|
+
# @todo Passing as parameter the tables names to apply triggers.
|
7
|
+
# @todo Change name for audit table.
|
8
|
+
# @todo If exist trigger then append to existing.
|
9
|
+
# @todo Backup if exist triggers.
|
10
|
+
# @todo Define expiration time for events.
|
11
|
+
|
12
|
+
module Mysqlaudit
|
13
|
+
class Audit
|
14
|
+
def initialize(host, user, password, schema)
|
15
|
+
$host = host
|
16
|
+
$user = user
|
17
|
+
$password = password
|
18
|
+
$schema = schema
|
19
|
+
|
20
|
+
connect
|
21
|
+
end
|
22
|
+
|
23
|
+
def connect()
|
24
|
+
begin
|
25
|
+
@mysql = Mysql2::Client.new(:host => $host,
|
26
|
+
:username => $user,
|
27
|
+
:password => $password,
|
28
|
+
:database => $schema)
|
29
|
+
rescue
|
30
|
+
puts "Can't connect to MySQL Server."
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_table()
|
36
|
+
if !has_table
|
37
|
+
sql = <<SQL
|
38
|
+
CREATE TABLE IF NOT EXISTS audits (
|
39
|
+
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
40
|
+
type enum('I', 'U', 'D') NOT NULL,
|
41
|
+
`table` char(64) NOT NULL,
|
42
|
+
`column` char(64) NOT NULL,
|
43
|
+
`primary_key` int(10) unsigned,
|
44
|
+
`old` TEXT DEFAULT NULL,
|
45
|
+
`new` TEXT DEFAULT NULL,
|
46
|
+
`trigger_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
47
|
+
PRIMARY KEY (id),
|
48
|
+
UNIQUE KEY id_UNIQUE (id)
|
49
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
50
|
+
SQL
|
51
|
+
|
52
|
+
@mysql.query(sql)
|
53
|
+
puts "Created table audits in #{$schema} database."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_table()
|
58
|
+
sql = "SELECT true AS has FROM information_schema.tables WHERE table_schema = '#{$schema}' AND table_name = 'audits';"
|
59
|
+
@mysql.query(sql).count == 1
|
60
|
+
end
|
61
|
+
|
62
|
+
def drop_table()
|
63
|
+
return unless has_table()
|
64
|
+
@mysql.query("DROP TABLE IF EXISTS audits;")
|
65
|
+
puts "Delete table audits in #{$schema} database."
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_tables()
|
69
|
+
sql = "SELECT table_name AS name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '#{$schema}' AND table_name <> 'audits';"
|
70
|
+
sql_result = @mysql.query(sql)
|
71
|
+
sql_result.map { |table| table['name']}
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_primary_key(table)
|
75
|
+
sql = "SELECT column_name AS name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='#{$schema}' AND TABLE_NAME='#{table}' AND column_key = 'PRI';"
|
76
|
+
@mysql.query(sql).first['name']
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_columns(table)
|
80
|
+
sql = "SELECT column_name AS name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='#{$schema}' AND TABLE_NAME='#{table}' AND column_key <> 'PRI';"
|
81
|
+
sql_result = @mysql.query(sql)
|
82
|
+
sql_result.map { |table| table['name']}
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_trigger(table, actionName)
|
86
|
+
if !has_trigger(table, actionName)
|
87
|
+
columns = get_columns(table)
|
88
|
+
key = get_primary_key(table)
|
89
|
+
|
90
|
+
if key
|
91
|
+
sql = "CREATE TRIGGER audit_#{table}_#{actionName.downcase} AFTER #{actionName.upcase} ON #{table}\nFOR EACH ROW BEGIN\n"
|
92
|
+
|
93
|
+
columns.each do | column |
|
94
|
+
case actionName.downcase
|
95
|
+
when :insert
|
96
|
+
sql << "INSERT INTO audits (type, `table`, `column`, primary_key, old, new) VALUES ('#{actionName[0,1].upcase}', '#{table}', '#{column}', NEW.#{key}, NULL, NEW.#{column});\n"
|
97
|
+
when :update
|
98
|
+
sql << "IF OLD.#{column} <> NEW.#{column} THEN\n"
|
99
|
+
sql << " INSERT INTO audits (type, `table`, `column`, primary_key, old, new) VALUES ('#{actionName[0,1].upcase}', '#{table}', '#{column}', NEW.#{key}, OLD.#{column}, NEW.#{column});\n"
|
100
|
+
sql << "END IF;\n"
|
101
|
+
when :delete
|
102
|
+
sql << "INSERT INTO audits (type, `table`, `column`, primary_key, old, new) VALUES ('#{actionName[0,1].upcase}', '#{table}', '#{column}', OLD.#{key}, OLD.#{column}, NULL);\n"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
sql << "END;"
|
107
|
+
|
108
|
+
@mysql.query(sql)
|
109
|
+
puts "Created trigger in #{table} table after #{actionName}."
|
110
|
+
else
|
111
|
+
puts "Impossible to create trigger in #{table}, not have primary key."
|
112
|
+
end
|
113
|
+
else
|
114
|
+
puts "Impossible to create trigger in #{table}, has a trigger."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def drop_trigger(table, actionName)
|
119
|
+
if has_trigger(table, actionName)
|
120
|
+
sql = "DROP TRIGGER IF EXISTS audit_#{table}_#{actionName};"
|
121
|
+
@mysql.query(sql)
|
122
|
+
puts "Deleted trigger in #{table} table after #{actionName}."
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def has_trigger(table, actionName)
|
127
|
+
sql = "SELECT true AS has FROM information_schema.triggers WHERE trigger_schema = '#{$schema}' AND trigger_name = 'audit_#{table}_#{actionName}';"
|
128
|
+
@mysql.query(sql).count == 1
|
129
|
+
end
|
130
|
+
|
131
|
+
def build_pivot_query(table, statement)
|
132
|
+
columns = get_columns($table)
|
133
|
+
key = get_primary_key($table)
|
134
|
+
|
135
|
+
case statement
|
136
|
+
when :insert
|
137
|
+
sql = <<SQL
|
138
|
+
SELECT CONCAT('/* ', trigger_at, ' */ DELETE FROM #{$table} WHERE id = ', MAX(primary_key),';') AS `row`
|
139
|
+
FROM audits
|
140
|
+
WHERE `type` = 'I'
|
141
|
+
AND `table` = '#{$table}'
|
142
|
+
GROUP BY primary_key
|
143
|
+
ORDER BY trigger_at, primary_key, `column` ASC;
|
144
|
+
SQL
|
145
|
+
when :delete
|
146
|
+
sql = "SELECT CONCAT('/* ', trigger_at, ' */ INSERT INTO #{$table} (#{key}, #{columns.join(', ')}) VALUES (', primary_key, ', ', "
|
147
|
+
columns.each do | column |
|
148
|
+
sql << " QUOTE(MAX(IF(`column` = '#{column}', `old`, NULL))), ', ', "
|
149
|
+
end
|
150
|
+
sql = sql.chomp(" ', ', ")
|
151
|
+
sql << "');'"
|
152
|
+
sql << ") AS `row` FROM audits WHERE `type` = 'D' AND `table` = '#{$table}' GROUP BY primary_key ORDER BY trigger_at, primary_key, `column` ASC;"
|
153
|
+
when :update
|
154
|
+
sql = "SELECT CONCAT('/* ', trigger_at, ' */ UPDATE users SET ', `column`, ' = ', QUOTE(old), ' WHERE id = ', primary_key, ';') AS `row`"
|
155
|
+
sql << "FROM audits WHERE `type` = 'U' AND `table` = '#{$table}' ORDER BY trigger_at, primary_key, `column` ASC;"
|
156
|
+
end
|
157
|
+
|
158
|
+
sql_result = @mysql.query(sql)
|
159
|
+
sql_result.each(:as => :array) do |row|
|
160
|
+
puts row
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def rollback(table, statement)
|
165
|
+
build_pivot_query(table, statement)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
data/lib/mysqlaudit.rb
ADDED
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mysqlaudit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicola Strappazzon C.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-14 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: MySQL tool for audit all tables with triggers.
|
14
|
+
email: nicola51980@gmail.com
|
15
|
+
executables:
|
16
|
+
- mysqlaudit
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/mysqlaudit
|
21
|
+
- lib/mysqlaudit/actions.rb
|
22
|
+
- lib/mysqlaudit/audit.rb
|
23
|
+
- lib/mysqlaudit/version.rb
|
24
|
+
- lib/mysqlaudit.rb
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.md
|
27
|
+
homepage: https://github.com/nicola51980/mysqlaudit
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubyforge_project:
|
47
|
+
rubygems_version: 2.0.5
|
48
|
+
signing_key:
|
49
|
+
specification_version: 4
|
50
|
+
summary: MySQL Audit Tool
|
51
|
+
test_files: []
|