Compare commits
No commits in common. "develop" and "develop" have entirely different histories.
10 changed files with 17 additions and 76 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -1,18 +1,5 @@
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## v1.2.1
|
|
||||||
### Fixed
|
|
||||||
- add default type of string
|
|
||||||
|
|
||||||
## v1.2.0
|
|
||||||
### Added
|
|
||||||
- add "lorem_word" faker
|
|
||||||
- add "lorem_sentence" faker
|
|
||||||
- add "lorem_paragraph" faker
|
|
||||||
- add "lorem_words_2" to "lorem_words_10" fakers
|
|
||||||
- add "lorem_sentences_2" to "lorem_sentences_10" fakers
|
|
||||||
- add "lorem_paragraphs_2" to "lorem_paragraphs_10" fakers
|
|
||||||
|
|
||||||
## v1.1.0
|
## v1.1.0
|
||||||
### Added
|
### Added
|
||||||
- PostgreSQL: manage all number types
|
- PostgreSQL: manage all number types
|
||||||
|
|
|
||||||
10
README.fr.md
10
README.fr.md
|
|
@ -31,10 +31,10 @@ rules:
|
||||||
name: company_name
|
name: company_name
|
||||||
- table: access_log
|
- table: access_log
|
||||||
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
||||||
truncate: true
|
delete: true
|
||||||
- table: user_ip
|
- table: user_ip
|
||||||
primary_key: [user_id, ip_id]
|
primary_key: [user_id, ip_id]
|
||||||
truncate: true
|
delete: true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Exécution
|
### Exécution
|
||||||
|
|
@ -61,12 +61,6 @@ database-anonymizer --dsn "postgres://postgres:postgres@localhost:5432/test" --s
|
||||||
|
|
||||||
#### Les autres
|
#### Les autres
|
||||||
|
|
||||||
- `"lorem_word"`
|
|
||||||
- `"lorem_sentence"`
|
|
||||||
- `"lorem_paragraph"`
|
|
||||||
- `"lorem_words_2"` to `"lorem_words_10"`
|
|
||||||
- `"lorem_sentences_2"` to `"lorem_sentences_10"`
|
|
||||||
- `"lorem_paragraphs_2"` to `"lorem_paragraphs_10"`
|
|
||||||
- `"address"`
|
- `"address"`
|
||||||
- `"address_buildingnumber"`
|
- `"address_buildingnumber"`
|
||||||
- `"address_city"`
|
- `"address_city"`
|
||||||
|
|
|
||||||
18
README.md
18
README.md
|
|
@ -1,8 +1,8 @@
|
||||||
# Database Anonymizer
|
# Database Anonimizer
|
||||||
|
|
||||||
**Database Anonymizer** is a tool written in GO that allows **anonymizing or deleting data from a MySQL or PostgreSQL database**.
|
**Database Anonymizer** is a tool written in GO that allows **anonymizing or deleting data from a MySQL or PostgreSQL database**.
|
||||||
|
|
||||||
It addresses various use cases such as **providing developers with an anonymized copy of a database** or **satisfying the need to anonymize or delete data in accordance with GDPR** (General Data Protection Regulation), depending on the retention periods defined in the processing register.
|
It addresses various use cases such as **providing developers with an anonymized copy of a database** or **satisfying the need to anonymize or delete data in accordance with GDPR (General Data Protection Regulation) requirements. data protection)**, depending on the retention periods. defined in the processing register.
|
||||||
|
|
||||||
The project includes a vast array of fakers. It also enables data generation via Twig-written templates. You can specify precise rules for each table or global rules applied to all tables in your configuration.
|
The project includes a vast array of fakers. It also enables data generation via Twig-written templates. You can specify precise rules for each table or global rules applied to all tables in your configuration.
|
||||||
|
|
||||||
|
|
@ -31,13 +31,13 @@ rules:
|
||||||
name: company_name
|
name: company_name
|
||||||
- table: access_log
|
- table: access_log
|
||||||
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
||||||
truncate: true
|
delete: true
|
||||||
- table: user_ip
|
- table: user_ip
|
||||||
primary_key: [user_id, ip_id]
|
primary_key: [user_id, ip_id]
|
||||||
truncate: true
|
delete: true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run
|
### Exécution
|
||||||
|
|
||||||
To display help, use `-h`:
|
To display help, use `-h`:
|
||||||
|
|
||||||
|
|
@ -56,17 +56,11 @@ database-anonymizer --dsn "postgres://postgres:postgres@localhost:5432/test" --s
|
||||||
|
|
||||||
#### Special fakers
|
#### Special fakers
|
||||||
|
|
||||||
- `"null"`: set `null`
|
- `"null"` : set `null`
|
||||||
- `""` or `"_"`: do nothing
|
- `""` or `"_"`: do nothing
|
||||||
|
|
||||||
#### Others
|
#### Others
|
||||||
|
|
||||||
- `"lorem_word"`
|
|
||||||
- `"lorem_sentence"`
|
|
||||||
- `"lorem_paragraph"`
|
|
||||||
- `"lorem_words_2"` to `"lorem_words_10"`
|
|
||||||
- `"lorem_sentences_2"` to `"lorem_sentences_10"`
|
|
||||||
- `"lorem_paragraphs_2"` to `"lorem_paragraphs_10"`
|
|
||||||
- `"address"`
|
- `"address"`
|
||||||
- `"address_buildingnumber"`
|
- `"address_buildingnumber"`
|
||||||
- `"address_city"`
|
- `"address_city"`
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ func (a *App) UpdateRows(c config.SchemaConfigAction, globalColumns map[string]s
|
||||||
updates = append(updates, database.GetNamedParameter(a.DbConfig.Type, col, len(values)+1))
|
updates = append(updates, database.GetNamedParameter(a.DbConfig.Type, col, len(values)+1))
|
||||||
values[len(values)+1] = value.FinalValue()
|
values[len(values)+1] = value.FinalValue()
|
||||||
} else {
|
} else {
|
||||||
updates = append(updates, fmt.Sprintf("%s=%s", database.EscapeColumn(a.DbConfig.Type, col), value.FinalValue()))
|
updates = append(updates, fmt.Sprintf("%s=%s", col, value.FinalValue()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +179,7 @@ func (a *App) UpdateRows(c config.SchemaConfigAction, globalColumns map[string]s
|
||||||
value := row[col]
|
value := row[col]
|
||||||
|
|
||||||
if !value.IsString || value.IsNull {
|
if !value.IsString || value.IsNull {
|
||||||
pkeys = append(pkeys, fmt.Sprintf("%s=%s", database.EscapeColumn(a.DbConfig.Type, col), value.FinalValue()))
|
pkeys = append(pkeys, fmt.Sprintf("%s=%s", col, value.FinalValue()))
|
||||||
} else {
|
} else {
|
||||||
pkeys = append(pkeys, database.GetNamedParameter(a.DbConfig.Type, col, len(values)+1))
|
pkeys = append(pkeys, database.GetNamedParameter(a.DbConfig.Type, col, len(values)+1))
|
||||||
values[len(values)+1] = value.FinalValue()
|
values[len(values)+1] = value.FinalValue()
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,12 @@ func EscapeTable(dbType, table string) string {
|
||||||
return fmt.Sprintf("\"%s\"", table)
|
return fmt.Sprintf("\"%s\"", table)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EscapeColumn(dbType, col string) string {
|
|
||||||
return EscapeTable(dbType, col)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetNamedParameter(dbType, col string, number int) string {
|
func GetNamedParameter(dbType, col string, number int) string {
|
||||||
if dbType == "mysql" {
|
if dbType == "mysql" {
|
||||||
return fmt.Sprintf("%s=?", EscapeColumn(dbType, col))
|
return fmt.Sprintf("%s=?", col)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s=$%d", EscapeColumn(dbType, col), number)
|
return fmt.Sprintf("%s=$%d", col, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsPgNumberType(value string) bool {
|
func IsPgNumberType(value string) bool {
|
||||||
|
|
@ -77,14 +73,13 @@ func GetRows(db *sql.DB, query, table, dbType string) map[int]map[string]data.Da
|
||||||
value := values[i]
|
value := values[i]
|
||||||
d := data.Data{
|
d := data.Data{
|
||||||
IsVirtual: false,
|
IsVirtual: false,
|
||||||
IsString: true,
|
|
||||||
IsNull: value == nil,
|
IsNull: value == nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
if value != nil {
|
if value != nil {
|
||||||
if dbType == "postgres" {
|
if dbType == "postgres" {
|
||||||
if len(columnsTypes[col]) == 0 {
|
if len(columnsTypes[col]) == 0 {
|
||||||
typeQuery := fmt.Sprintf("SELECT pg_typeof(%s) as value FROM %s", EscapeColumn(dbType, col), EscapeTable(dbType, table))
|
typeQuery := fmt.Sprintf("SELECT pg_typeof(%s) as value FROM %s", col, EscapeTable(dbType, table))
|
||||||
db.QueryRow(typeQuery).Scan(&typeValue)
|
db.QueryRow(typeQuery).Scan(&typeValue)
|
||||||
columnsTypes[col] = typeValue
|
columnsTypes[col] = typeValue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,12 @@ func TestEscapeTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEscapeColumn(t *testing.T) {
|
|
||||||
if EscapeColumn("mysql", "foo") != "`foo`" {
|
|
||||||
t.Fatalf("TestEscapeColumn: mysql check failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
if EscapeColumn("postgres", "foo") != "\"foo\"" {
|
|
||||||
t.Fatalf("TestEscapeColumn: postgres check failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetNamedParameter(t *testing.T) {
|
func TestGetNamedParameter(t *testing.T) {
|
||||||
if GetNamedParameter("mysql", "foo", 1) != "`foo`=?" {
|
if GetNamedParameter("mysql", "foo", 1) != "foo=?" {
|
||||||
t.Fatalf("TestGetNamedParameter: mysql check failed")
|
t.Fatalf("TestGetNamedParameter: mysql check failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if GetNamedParameter("postgres", "foo", 1) != "\"foo\"=$1" {
|
if GetNamedParameter("postgres", "foo", 1) != "foo=$1" {
|
||||||
t.Fatalf("TestGetNamedParameter: postgres check failed")
|
t.Fatalf("TestGetNamedParameter: postgres check failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ rules:
|
||||||
name: company_name
|
name: company_name
|
||||||
- table: access_log
|
- table: access_log
|
||||||
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
query: 'select * from access_log where date < (NOW() - INTERVAL 6 MONTH)'
|
||||||
truncate: true
|
delete: true
|
||||||
- table: user_ip
|
- table: user_ip
|
||||||
primary_key: [user_id, ip_id]
|
primary_key: [user_id, ip_id]
|
||||||
truncate: true
|
delete: true
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@ package faker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-loremipsum/loremipsum"
|
|
||||||
base_faker "github.com/jaswdr/faker"
|
base_faker "github.com/jaswdr/faker"
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -12,26 +10,12 @@ type FakeManager struct {
|
||||||
Fakers map[string]func() string
|
Fakers map[string]func() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLoremFaker() *loremipsum.LoremIpsum {
|
|
||||||
return loremipsum.NewWithSeed(rand.Int63())
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeManager() FakeManager {
|
func NewFakeManager() FakeManager {
|
||||||
manager := FakeManager{}
|
manager := FakeManager{}
|
||||||
datas := make(map[string]func() string)
|
datas := make(map[string]func() string)
|
||||||
|
|
||||||
fake := base_faker.New()
|
fake := base_faker.New()
|
||||||
|
|
||||||
datas["lorem_word"] = func() string { return NewLoremFaker().Word() }
|
|
||||||
datas["lorem_sentence"] = func() string { return NewLoremFaker().Sentence() }
|
|
||||||
datas["lorem_paragraph"] = func() string { return NewLoremFaker().Paragraph() }
|
|
||||||
|
|
||||||
for i := 2; i <= 10; i++ {
|
|
||||||
datas[fmt.Sprintf("lorem_words_%d", i)] = func() string { return NewLoremFaker().Words(i) }
|
|
||||||
datas[fmt.Sprintf("lorem_sentences_%d", i)] = func() string { return NewLoremFaker().Sentences(i) }
|
|
||||||
datas[fmt.Sprintf("lorem_paragraphs_%d", i)] = func() string { return NewLoremFaker().Paragraphs(i) }
|
|
||||||
}
|
|
||||||
|
|
||||||
datas["address"] = func() string { return fake.Address().Address() }
|
datas["address"] = func() string { return fake.Address().Address() }
|
||||||
datas["address_buildingnumber"] = func() string { return fake.Address().BuildingNumber() }
|
datas["address_buildingnumber"] = func() string { return fake.Address().BuildingNumber() }
|
||||||
datas["address_city"] = func() string { return fake.Address().City() }
|
datas["address_city"] = func() string { return fake.Address().City() }
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -15,7 +15,6 @@ require (
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||||
github.com/go-loremipsum/loremipsum v1.1.3 // indirect
|
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -5,8 +5,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-loremipsum/loremipsum v1.1.3 h1:ZRhA0ZmJ49lGe5HhWeMONr+iGftWDsHfrYBl5ktDXso=
|
|
||||||
github.com/go-loremipsum/loremipsum v1.1.3/go.mod h1:OJQjXdvwlG9hsyhmMQoT4HOm4DG4l62CYywebw0XBoo=
|
|
||||||
github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4=
|
github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4=
|
||||||
github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
github.com/jaswdr/faker v1.19.1 h1:xBoz8/O6r0QAR8eEvKJZMdofxiRH+F0M/7MU9eNKhsM=
|
github.com/jaswdr/faker v1.19.1 h1:xBoz8/O6r0QAR8eEvKJZMdofxiRH+F0M/7MU9eNKhsM=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue