Repository: nixys/nxs-data-anonymizer Branch: main Commit: ede8bfc83dc2 Files: 77 Total size: 423.1 KB Directory structure: gitextract_88iwtv_2/ ├── .docker/ │ └── Dockerfile ├── .github/ │ ├── release.yml │ └── workflows/ │ └── publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── ctx/ │ ├── args.go │ ├── conf.go │ └── context.go ├── doc/ │ └── examples/ │ ├── drop/ │ │ ├── MySQL/ │ │ │ ├── input.sql │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output.sql │ │ ├── PostgreSQL/ │ │ │ ├── input │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output │ │ └── Readme.md │ ├── filters/ │ │ ├── MySQL/ │ │ │ ├── input.sql │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output.sql │ │ ├── PostgreSQL/ │ │ │ ├── input │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output │ │ └── Readme.md │ ├── links/ │ │ ├── MySQL/ │ │ │ ├── input.sql │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output.sql │ │ ├── PostgreSQL/ │ │ │ ├── input │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output │ │ └── Readme.md │ ├── security/ │ │ ├── MySQL/ │ │ │ ├── input.sql │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output.sql │ │ ├── PostgreSQL/ │ │ │ ├── input │ │ │ ├── nxs-data-anonymizer.conf │ │ │ └── output │ │ └── Readme.md │ └── variables/ │ ├── MySQL/ │ │ ├── input.sql │ │ ├── nxs-data-anonymizer.conf │ │ └── output.sql │ ├── PostgreSQL/ │ │ ├── input │ │ ├── nxs-data-anonymizer.conf │ │ └── output │ └── Readme.md ├── ds/ │ └── mysql/ │ └── mysql.go ├── go.mod ├── go.sum ├── interfaces/ │ └── anonymizer.go ├── main.go ├── misc/ │ ├── errors.go │ ├── security.go │ ├── template.go │ ├── token.go │ └── values.go ├── modules/ │ ├── anonymizers/ │ │ ├── mysql/ │ │ │ ├── .testdata/ │ │ │ │ ├── mysql_test.dos.in.sql │ │ │ │ ├── mysql_test.dos.out.sql │ │ │ │ ├── mysql_test.in.sql │ │ │ │ └── mysql_test.out.sql │ │ │ ├── dh.go │ │ │ ├── mysql.go │ │ │ ├── mysql_test.go │ │ │ ├── security_types.go │ │ │ └── states.go │ │ └── pgsql/ │ │ ├── .testdata/ │ │ │ ├── pgsql_test.dos.in.sql │ │ │ ├── pgsql_test.dos.out.sql │ │ │ ├── pgsql_test.in.sql │ │ │ └── pgsql_test.out.sql │ │ ├── dh.go │ │ ├── pgsql.go │ │ ├── pgsql_test.go │ │ ├── security_types.go │ │ └── states.go │ ├── filters/ │ │ └── relfilter/ │ │ ├── column.go │ │ ├── filter.go │ │ └── filter_test.go │ └── progress_reader/ │ └── progress_reader.go └── routines/ └── anonymizer/ └── anonymizer.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .docker/Dockerfile ================================================ FROM golang:1.21-bullseye as build-env ARG APP_VERSION WORKDIR /usr/src/app ADD ./ /usr/src/app RUN go build -ldflags "-X github.com/nixys/nxs-data-anonymizer/ctx.version=$APP_VERSION" -o /nxs-data-anonymizer FROM alpine RUN apk update --no-cache && apk add --no-cache tar postgresql-client mysql-client libc6-compat s3cmd COPY --from=build-env /nxs-data-anonymizer / ================================================ FILE: .github/release.yml ================================================ # .github/release.yml changelog: exclude: labels: - ignore-for-release categories: - title: Breaking Changes 🛠 labels: - Semver-Major - breaking-change - title: Exciting New Features 🎉 labels: - Semver-Minor - enhancement - title: Fixes 🪲 labels: - Semver-Patch - bug - title: Other Changes labels: - "*" ================================================ FILE: .github/workflows/publish.yml ================================================ name: Release on: push: tags: - 'v*' jobs: build-and-publish-release: runs-on: ${{ matrix.os }} strategy: matrix: include: - os: ubuntu-latest TARGET: arm64 - os: ubuntu-latest TARGET: amd64 steps: - name: Building ${{ matrix.TARGET }} run: echo "${{ matrix.TARGET }}" - uses: actions/checkout@v4 - uses: actions/setup-go@v3 name: Set up Go with: go-version: 1.21 - name: Get version id: get_version uses: battila7/get-version-action@v2 - name: Build run: GOOS=linux GOARCH=${{ matrix.TARGET }} CGO_ENABLED=0 go build -ldflags="-s -w -X github.com/nixys/nxs-data-anonymizer/ctx.version=${{ steps.get_version.outputs.version-without-v }}" -v -o nxs-data-anonymizer - name: Compress uses: a7ul/tar-action@v1.1.2 id: compress with: command: c files: | ./nxs-data-anonymizer ./README.md ./LICENSE outPath: nxs-data-anonymizer-${{ matrix.TARGET }}.tar.gz - uses: actions/upload-artifact@v4 with: name: nxs-data-anonymizer-${{ matrix.TARGET }}.tar.gz path: nxs-data-anonymizer-${{ matrix.TARGET }}.tar.gz - uses: softprops/action-gh-release@v1 name: Upload binaries to release if: github.ref_type == 'tag' with: files: nxs-data-anonymizer-${{ matrix.TARGET }}.tar.gz prerelease: ${{ contains(github.ref_name, 'rc') }} generate_release_notes: true append_body: true build-and-push-docker: runs-on: ubuntu-latest environment: secure steps: - name: Checkout uses: actions/checkout@v4 - name: Get version id: get_version uses: battila7/get-version-action@v2 - name: Login to Registry Hub uses: docker/login-action@v2 with: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Docker meta for app id: meta-app uses: docker/metadata-action@v4 with: images: | nixyslab/nxs-data-anonymizer - name: Build and push app uses: docker/build-push-action@v4 with: context: . file: .docker/Dockerfile push: true tags: ${{ steps.meta-app.outputs.tags }} build-args: APP_VERSION=${{ steps.get_version.outputs.version-without-v }}" ================================================ FILE: .gitignore ================================================ /.project /.vscode /.tmp ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2023 Nixys Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ ![photo_2023-07-28_15-28-52](https://github.com/nixys/nxs-data-anonymizer/assets/27485608/165a90a0-929f-460b-8dbd-2903c0d91f36) # nxs-data-anonymizer [![Telegram News][tg-news-badge]][tg-news-url] [![Telegram Chat][tg-chat-badge]][tg-chat-url] ## Introduction nxs-data-anonymizer is a tool for anonymizing **PostgreSQL** and **MySQL/MariaDB/Percona** databases' dump. ### Features - Supported databases and versions: - PostgreSQL (9/10/11/12/13/14/15/all versions) - MySQL/MariaDB/Percona (5.7/8.0/8.1/all versions) - Flexible data faking based on: - Go templates and [Sprig template’s library](https://masterminds.github.io/sprig/) like [Helm](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/). You may also use values of other columns for same row to build more flexible rules - External commands you may execute to create table field values - Security enforcement rules - Link cells across the database to generate the same values - Stream data processing. It means that you can a use the tool through a pipe in command line and redirect dump from source DB directly to the destination DB with required transformations - Easy to integrate into your CI/CD ### Who can use the tool Development and project teams which are dealing with production and test/dev/stage or dynamic namespaces with databases and need to ensure security and prevent data leaks. ## Quickstart Inspect your database structure and [set up](#settings) the nxs-data-anonymizer config in accordance with the sensitive data you need to anonymize. You are able to use this tool in any way you want. Three most common ways are described below. #### Console In order to operate with your database anonymization via console you need to go through the following steps: - Download and untar the nxs-data-anonymizer [binary](https://github.com/nixys/nxs-data-anonymizer/releases) - Run the nxs-data-anonymizer through the command line with [arguments](#command-line-arguments) you want to use For example, use the following command if you need to anonymize your PostgreSQL database from production to dev on fly (PostgreSQL Client need to be installed): ```console export PGPASSWORD=password; pg_dump -U postgres prod | /path/to/nxs-data-anonymizer -t pgsql -c /path/to/nxs-data-anonymizer.conf | psql -U postgres dev ``` #### GitLab CI This section describes how to integrate nxs-data-anonymizer into your GitLab CI. You may add jobs presented below into your `.gitlab-ci.yml` and adjust it for yourself. ##### Job: anonymize prod Job described in this section is able to perform the following tasks: - Run when special tag for `main` branch is set - Create a `production` database dump, anonymize and upload it into s3 bucket Job sample: ```yaml anonymize: stage: anonymize image: nixyslab/nxs-data-anonymizer:latest variables: GIT_STRATEGY: none PG_HOST: ${PG_HOST_PROD} PG_USER: ${PG_USER_PROD} PGPASSWORD: ${PG_PASS_PROD} before_script: - echo "${S3CMD_CFG}" > ~/.s3cmd - echo "${NXS_DA_CFG}" > /nxs-data-anonymizer.conf script: - pg_dump -h ${PG_HOST} -U ${PG_USER} --schema=${PG_SCHEMA} ${PG_DATABASE} | /nxs-data-anonymizer -t pgsql -c /nxs-data-anonymizer.conf | gzip | s3cmd put - s3://bucket/anondump.sql.gz only: - /^v.*$/ except: - branches - merge_requests ``` ##### Job: update stage Job described in this section deals with the following: - Manual job for `stage` branch - Download the anonymized dump from s3 bucket and load into `stage` database Job sample: ```yaml restore-stage: stage: restore image: nixyslab/nxs-data-anonymizer:latest variables: GIT_STRATEGY: none PG_HOST: ${PG_HOST_STAGE} PG_USER: ${PG_USER_STAGE} PGPASSWORD: ${PG_PASS_STAGE} before_script: - echo "${S3CMD_CFG}" > ~/.s3cmd script: - s3cmd --no-progress --quiet get s3://bucket/anondump.sql.gz - | gunzip | psql -h ${PG_HOST} -U ${PG_USER} --schema=${PG_SCHEMA} ${PG_DATABASE} only: - stage when: manual ``` ##### CI/CD variables This section contains a description of CI/CD variables used in GitLab CI job samples above. ###### General | Variable | Description | | :---: | :---: | |`S3CMD_CFG` | S3 storage config | |`PG_SCHEMA`| PgSQL schema | |`PG_DATABASE`|PgSQL database name| ###### Production | Variable | Description | | :---: | :---: | |`NXS_DA_CFG`|nxs-data-anonymizer config| |`PG_HOST_PROD` |PgSQL host| |`PG_USER_PROD`|PgSQL user| |`PG_PASS_PROD`|PgSQL password| ###### Stage | Variable | Description | | :---: | :---: | |`PG_HOST_STAGE`|PgSQL host| |`PG_USER_STAGE`|PgSQL user| |`PG_PASS_STAGE`|PgSQL password| #### GitHub Actions This section describes how to integrate nxs-data-anonymizer into your GitHub Actions. You may add jobs presented below into your `.github` workflows and adjust it for yourself. ##### Job: anonymize prod Job described in this section is able to perform the following tasks: - Run when special tag is set - Create a `production` database dump, anonymize and upload it into s3 bucket ```yaml on: push: tags: - v*.* jobs: anonymize: runs-on: ubuntu-latest container: image: nixyslab/nxs-data-anonymizer:latest env: PG_HOST: ${{ secrets.PG_HOST_PROD }} PG_USER: ${{ secrets.PG_USER_PROD }} PGPASSWORD: ${{ secrets.PG_PASS_PROD }} PG_SCHEMA: ${{ secrets.PG_SCHEMA }} PG_DATABASE: ${{ secrets.PG_DATABASE }} steps: - name: Create services configs run: | echo "${{ secrets.S3CMD_CFG }}" > ~/.s3cmd echo "${{ secrets.NXS_DA_CFG }}" > /nxs-data-anonymizer.conf - name: Anonymize run: | pg_dump -h ${PG_HOST} -U ${PG_USER} --schema=${PG_SCHEMA} ${PG_DATABASE} | /nxs-data-anonymizer -t pgsql -c /nxs-data-anonymizer.conf | gzip | s3cmd put - s3://bucket/anondump.sql.gz ``` ##### Job: update stage Job described in this section deals with the following: - Manual job - Download the anonymized dump from s3 bucket and load into `stage` database ```yaml on: workflow_dispatch jobs: restore-stage: runs-on: ubuntu-latest container: image: nixyslab/nxs-data-anonymizer:latest env: PG_HOST: ${{ secrets.PG_HOST_STAGE }} PG_USER: ${{ secrets.PG_USER_STAGE }} PGPASSWORD: ${{ secrets.PG_PASS_STAGE }} PG_SCHEMA: ${{ secrets.PG_SCHEMA }} PG_DATABASE: ${{ secrets.PG_DATABASE }} steps: - name: Create services configs run: | echo "${{ secrets.S3CMD_CFG }}" > ~/.s3cmd - name: Restore run: | s3cmd --no-progress --quiet get s3://bucket/anondump.sql.gz - | gunzip | psql -h ${PG_HOST} -U ${PG_USER} --schema=${PG_SCHEMA} ${PG_DATABASE} ``` ##### GitHub Actions secrets This section contains a description of secrets used in GitHub Actions job samples above. ###### General | Variable | Description | | :---: | :---: | |`S3CMD_CFG` | S3 storage config | |`PG_SCHEMA`| PgSQL schema | |`PG_DATABASE`|PgSQL database name| ###### Production | Variable | Description | | :---: | :---: | |`NXS_DA_CFG`|nxs-data-anonymizer config| |`PG_HOST_PROD` |PgSQL host| |`PG_USER_PROD`|PgSQL user| |`PG_PASS_PROD`|PgSQL password| ###### Stage | Variable | Description | | :---: | :---: | |`PG_HOST_STAGE`|PgSQL host| |`PG_USER_STAGE`|PgSQL user| |`PG_PASS_STAGE`|PgSQL password| ### Settings Default configuration file path: `/nxs-data-anonymizer.conf`. The file is represented in yaml. #### Command line arguments | Argument | Short | Required | Having value | Default value | Description | | :---: | :---: | :---: | :---: | :---: |--- | | `--help` | `-h` | No | No | - | Show program help message | | `--version` | `-v` | No | No | - | Show program version | | `--conf` | `-c` | No | Yes | `/nxs-data-anonymizer.conf` | Configuration file path | | `--input` | `-i` | No | Yes | - | File to read data from. If not specified `stdin` will be used | | `--log-format` | `-l` | No | Yes | `json` | Log file format. You are available to use either `json` or `plain` value | | `--output` | `-o` | No | Yes | - | File to write data to. If not specified `stdout` will be used | | `--type` | `-t` | Yes | Yes | - | Database dump file type. Available values: `pgsql`, `mysql` | #### General settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `logfile` | String | No | `stderr` | Log file path. You may also use `stdout` and `stderr` | | `loglevel` | String | No | `info` | Log level. Available values: `debug`, `warn`, `error` and `info` | | `progress` | [Progress](#progress-settings) | No | - | Anonymization progress logging | | `variables` | Map of [Variables](#variables-settings) (key: variable name) | No | - | Global variables to be used in a filters. Variables are set at the init of application and remain unchanged during the runtime | | `link` | Slice of [Link](#link-settings) | No | - | Rules to link specified columns across the database | | `filters` | Map of [Filters](#filters-settings) (key: table name) | No | - | Filters set for specified tables (key as a table name). Note: for PgSQL you also need to specify a scheme (e.g. `public.tablename`) | | `security` | [Security](#security-settings) | No | - | Security enforcement for anonymizer | ##### Progress settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `rhythm` | String | No | `0s` | Frequency write into the log a read bytes count. Progress will be written to the log only when this option is specified and has none-zero value. You may use a human-readable values (e.g. `30s`, `5m`, etc) | | `humanize` | Bool | No | `false` | Set this option to `true` if you need to write into the log a read bytes count in a human-readable format. On `false` raw bytes count will be written to the log | ##### Variables settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `type` | String | No | `template` | Type of field `value`: `template` and `command` are available | | `value` | String | Yes | - | The value to be used as global variable value within the filters. In accordance with the `type` this value may be either `Go template` or `command`. See below for details| ##### Link settings Link is used to create the same data with specified rules for different cells across the database. Each link element has following properties: - Able to contain multiple tables and columns for each table - All specified cells with the same data before anonymization will have same data after - One common rule to generate new values | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `type` | String | No | `template` | Type of field `value`: `template` and `command` are available | | `value` | String | Yes | - | The value to be used to replace at every cell in specified column. In accordance with the `type` this value may be either `Go template` or `command`. See below for details| | `unique` | Bool | No | `false` | If true checks the generated value for cell is unique whole an all columns specified for `link` element | ##### Filters settings Filters description for specified table. | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `columns` | Map of [Columns](#columns-settings) (key: column name) | No | - | Filter rules for specified columns of table (key as a column name) | ###### Columns settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `type` | String | No | `template` | Type of field `value`: `template` and `command` are available | | `value` | String | Yes | - | The value to be used to replace at every cell in specified column. In accordance with the `type` this value may be either `Go template` or `command`. See below for details| | `unique` | Bool | No | `false` | If true checks the generated value for cell is unique whole the column | **Go template** To anonymize a database fields you may use a Go template with the [Sprig template library's](https://masterminds.github.io/sprig/) functions. Additional filter functions: - `null`: set a field value to `NULL` - `isNull`: compare a field value with `NULL` - `drop`: drop whole row. If table has filters for several columns and at least one of them returns drop value, whole row will be skipped during the anonymization process You may also use the following data in a templates: - Current table name. Statement: `{{ .TableName }}` - Current column name. Statement: `{{ .CurColumnName }}` - Values of other columns in the rules for same row (with values before substitutions). Statement: `{{ .Values.COLUMN_NAME }}` (e.g.: `{{ .Values.username }}`) - Global variables. Statement: `{{ .Variables.VARIABLE_NAME }}` (e.g.: `{{ .Variables.password }}`) - Raw column data type. Statement: `{{ .ColumnTypeRaw }}` - Regex's capturing groups for the column data type. This variable has array type so you need to use `range` or `index` to access specific element. Statement: `{{ index .ColumnTypeGroups 0 0 }}`. See [Types](#types-settings) for details **Command** To anonymize a database fields you may use a commands (scripts or binaries) with any logic you need. The command's concept has following properties: - The command's `stdout` will be used as a new value for the anonymized field - Command must return zero exit code, otherwise nxs-data-anonymizer will falls with error (in this case `stderr` will be used as an error text) - Environment variables with the row data are available within the command: - `ENVVARTABLE`: contains a name of the current table - `ENVVARCURCOLUMN`: contains the current column name - `ENVVARCOLUMN_{COLUMN_NAME}`: contains values (before substitutions) for all columns for the current row - `ENVVARGLOBAL_{VARIABLE_NAME}`: contains value for specified global variable - `ENVVARCOLUMNTYPERAW`: contains raw column data type - `ENVVARCOLUMNTYPEGROUP_{GROUP_NUM}_{SUBGROUPNUM}`: contains regex's capturing groups for the column data type. See [Types](#types-settings) for details ##### Security settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `policy` | [Policy](#policy-settings) | No | - | Security policy for entities | | `exceptions` | [Exceptions](exceptions-settings) | No | - | Exceptions for entities | | `defaults` | [Defaults](defaults-settings) | No | - | Default filters for entities | ###### Policy settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `tables` | String | No | `pass` | Security policy for tables. If value `skip` is used all undescribed tables in config will be skipped while anonymization | | `columns` | String | No | `pass` | Security policy for columns. If value `randomize` is used all undescribed columns in config will be randomized (with default rules in accordance to types) while anonymization | _Values to masquerade a columns in accordance with the types see below._ **PgSQL:** | Type | Value to masquerade | |---|:---:| | `smallint` | `0` | | `integer` | `0` | | `bigint` | `0` | | `smallserial` | `0` | | `serial` | `0` | | `bigserial` | `0` | | `decimal` | `0.0` | | `numeric` | `0.0` | | `real` | `0.0` | | `double` | `0.0` | | `character` | `randomized character data"` | | `bpchar` | `randomized bpchar data` | | `text` | `randomized text data` | **MySQL:** | Type | Value to masquerade | |---|:---:| | `bit` | `0` | | `bool` | `0` | | `boolean` | `0` | | `tinyint` | `0` | | `smallint` | `0` | | `mediumint` | `0` | | `int` | `0` | | `integer` | `0` | | `bigint` | `0` | | `float` | `0.0` | | `double` | `0.0` | | `double precision` | `0.0` | | `decimal` | `0.0` | | `dec` | `0.0` | | `char` | `randomized char` (String will be truncated to "COLUMN_SIZE" length.)| | `varchar` | `randomized varchar` (String will be truncated to "COLUMN_SIZE" length.) | | `tinytext` | `randomized tinytext` | | `text` | `randomized text` | | `mediumtext` | `randomized mediumtext` | | `longtext` | `randomized longtext` | | `enum` | Last value from `enum` | | `set` | Last value from `set` | | `date` | `2024-01-01` | | `datetime` | `2024-01-01 00:00:00` | | `timestamp` | `2024-01-01 00:00:00` | | `time` | `00:00:00` | | `year` | `2024` | | `json` | `{"randomized": "json_data"}` | | `binary` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | | `varbinary` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | | `tinyblob` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | | `blob` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | | `mediumblob` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | | `longblob` | `cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=` | ###### Exceptions settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `tables` | Slice of strings | No | - | Table names without filters which are not be skipped while anonymization if option `security.policy.tables` set to `skip` | | `columns` | Slice of strings | No | - | Column names (in any table) without filters which are not be randomized while anonymization if option `security.policy.columns` set to `randomize` | ###### Defaults settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `columns` | Map of Filters | No | - | Default filter for columns (in any table). That filters will be applied for columns with this names without described filters | | `types` | Slice of [Types](#types-settings) | No | - | Custom filters for types (in any table). With this filter rules you may override default filters for types | ###### Types settings | Option | Type | Required | Default value | Description | |--- | :---: | :---: | :---: |--- | | `regex` | String | Yes | - | Regular expression. Will be checked for match for column data type (in `CREATE TABLE` section). Able to use capturing groups within the regex that available as an additional variable data in the filters (see [Columns](#columns-settings) for details). This ability helps to create more flexible rules to generate the cells value in accordance with data type features | | `rule` | [Columns](#columns-settings) | Yes | - | Rule will be applied columns with data types matched for specified regular expression | #### Example Imagine you have a simple database with two tables `users` and `posts` in your production PgSQL like this: | id | username | password | api_key | | :---: | :---: | :---: | :---: | | 1 | `admin` | `ZjCX6wUxtXIMtip` | `epezyj0cj5rqrdtxklnzxr3f333uibtz6avek7926141t1c918` | | 2 | `alice` | `tuhjLkgwwetiwf8` | `2od4vfsx2irj98hgjaoi6n7wjr02dg79cvqnmet4kyuhol877z` | | 3 | `bob` | `AjRzvRp3DWo6VbA` | `owp7hob5s3o083d5hmursxgcv9wc4foyl20cbxbrr73egj6jkx` | | id | poster_id | title | content | | :---: | :---: | :---: | :---: | | 1 | 1 | `example_post_1` | `epezyj0cj5rqrdtxklnzxr3f333uibtz6avek7926141t1c918` | | 2 | 2 | `example_post_2` | `2od4vfsx2irj98hgjaoi6n7wjr02dg79cvqnmet4kyuhol877z` | | 3 | 3 | `example_post_3` | `owp7hob5s3o083d5hmursxgcv9wc4foyl20cbxbrr73egj6jkx` | | 4 | 1 | `example_post_4` | `epezyj0cj5rqrdtxklnzxr3f333uibtz6avek7926141t1c918` | | 5 | 2 | `example_post_5` | `2od4vfsx2irj98hgjaoi6n7wjr02dg79cvqnmet4kyuhol877z` | | 6 | 3 | `example_post_6` | `owp7hob5s3o083d5hmursxgcv9wc4foyl20cbxbrr73egj6jkx` | You need to get a dump with fake values: - For `admin`: preset fixed value for a password and API key to avoid the need to change an app settings in your dev/test/stage or local environment after downloading the dump. - For others: usernames in format `user_N` (where `N` it is a user ID) and unique random passwords and API keys. - Need to preserve data mapping between `users` and `posts` tables in `id` and `poster_id` columns - Need to randomize contents of `content` column. In accordance with these conditions, the nxs-data-anonymizer config may look like this: ```yaml variables: #Global variables. adminPassword: type: template value: "preset_admin_password" adminAPIKey: value: "preset_admin_api_key" #Block defining rules of behavior with fields and tables for which filters are not specified. security: # Specifies the required actions for tables and columns that are not specified in the configuration. policy: tables: skip columns: randomize # Excludes policy actions for the specified tables and columns. exceptions: tables: - public.posts columns: - title # Overrides the default policy actions for the columns specified in this block. The value is generated once and substituted into all instances of the field. defaults: columns: content: value: "{{- randAlphaNum 20 -}}" #Here you define the rules that allow you to preserve the mapping of values ​​between tables. link: - rule: #Value generation rule. value: "{{ randInt 1 15 }}" unique: true with: #Tables and columns to which the rule is applied. public.users: - id public.posts: - poster_id #Block describing replacement rules for fields. filters: public.users: columns: username: value: "{{ if eq .Values.username \"admin\" }}{{ .Values.username }}{{ else }}user_{{ .Values.id }}{{ end }}" password: type: command value: /path/to/script.sh unique: true api_key: value: "{{ if eq .Values.username \"admin\" }}{{ .Variables.adminAPIKey }}{{ else }}{{- randAlphaNum 50 | nospace | lower -}}{{ end }}" unique: true ``` The `/path/to/script.sh` script content is following: ```bash #!/bin/bash # Print preset password if current user is admin if [ "$ENVVARCOLUMN_username" == "admin" ]; then echo -n "$ENVVARGLOBAL_adminPassword" exit 0 fi # Generate password for other users p=$(pwgen -s 5 1 2>&1) if [ ! $? -eq 0 ]; then # On error print message to stderr and exit with non zero code echo -n "$p" >&2 exit 1 fi # Print generated password echo $p | tr -d '\n' exit 0 ``` Now you may execute the following command in order to load anonymized data into your dev DB: ``` pg_dump ... | ./nxs-data-anonymizer -c filters.conf | psql -h localhost -U user example ``` As a result: | id | username | password | api_key | | :---: | :---: | :---: | :---: | | 5 | `admin` | `preset_admin_password` | `preset_admin_api_key` | | 4 | `user_2` | `Pp4HY` | `dhx4mccxyd8ux5uf1khpbqsws8qqeqs4efex1vhfltzhtjcwcu` | | 7 | `user_3` | `vu5TW` | `lgkkq3csskuyew8fr52vfjjenjzudokmiidg3cohl2bertc93x` | | id | poster_id | title | content | | :---: | :---: | :---: | :---: | | 1 | 5 | `example_post_1` | `EDlT6bGXJ2LOS7CE2E4b` | | 2 | 4 | `example_post_2` | `EDlT6bGXJ2LOS7CE2E4b` | | 3 | 7 | `example_post_3` | `EDlT6bGXJ2LOS7CE2E4b` | | 4 | 5 | `example_post_4` | `EDlT6bGXJ2LOS7CE2E4b` | | 5 | 4 | `example_post_5` | `EDlT6bGXJ2LOS7CE2E4b` | | 6 | 7 | `example_post_6` | `EDlT6bGXJ2LOS7CE2E4b` | It's easy. You can find more examples in doc/examples. ## Roadmap Following features are already in backlog for our development team and will be released soon: - [x] Global variables with the templated values you may use through the filters for all tables and columns - [x] Ability to delete tables and rows from faked dump - [ ] Ability to output into log a custom messages. It’s quite useful it order to obtain some generated data like admin passwords, etc - [ ] Support of a big variety of databases ## Feedback For support and feedback please contact me: - telegram: [@borisershov](https://t.me/borisershov) - e-mail: b.ershov@nixys.io For news and discussions subscribe the channels: - Telegram community (news): [@nxs_data_anonymizer](https://t.me/nxs_data_anonymizer) - Telegram community (chat): [@nxs_data_anonymizer_chat](https://t.me/nxs_data_anonymizer_chat) ## License nxs-data-anonymizer is released under the [Apache License 2.0](LICENSE). [tg-news-badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnxs_data_anonymizer [tg-chat-badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnxs_data_anonymizer_chat [tg-news-url]: https://t.me/nxs_data_anonymizer [tg-chat-url]: https://t.me/nxs_data_anonymizer_chat [aica-badge]: https://img.shields.io/badge/AI-Code%20Assist-EB9FDA [aica-url]: https://app.commanddash.io/agent?github=https://github.com/nixys/nxs-data-anonymizer ================================================ FILE: ctx/args.go ================================================ package ctx import ( "fmt" "os" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/pborman/getopt/v2" ) const ( confPathDefault = "/nxs-data-anonymizer.conf" ) var version string // Args contains arguments value read from command line type Args struct { ConfigPath string LogFormat LogFormat Input *string Output *string Cleanup bool DBType DBType } // ArgsRead reads arguments from command line func ArgsRead() (Args, error) { args := getopt.New() helpFlag := args.BoolLong( "help", 'h', "Show help") versionFlag := args.BoolLong( "version", 'v', "Show program version") confPath := args.StringLong( "conf", 'c', confPathDefault, fmt.Sprintf("Config file path")) input := args.StringLong( "input", 'i', "", "Input file. If not set `stdin` is used") logformat := args.EnumLong( "log-format", 'l', []string{ string(LogFormatJSON), string(LogFormatPlain), }, string(LogFormatJSON), fmt.Sprintf("Log file format. Values `%s` or `%s` are available", LogFormatJSON, LogFormatPlain), ) output := args.StringLong( "output", 'o', "", "Output file. If not set `stdout` is used") dbType := args.EnumLong( "type", 't', []string{ string(DBTypeMySQL), string(DBTypePgSQL), }, "", fmt.Sprintf("Database type you need to operate. Values `%s` or `%s` are available", DBTypePgSQL, DBTypeMySQL), ) cleanup := args.BoolLong( "cleanup", 'C', "Clean up destination database (experimental). Available only for MySQL") args.Parse(os.Args) /* Show help */ if *helpFlag == true { argsHelp(args) return Args{}, misc.ErrArgSuccessExit } /* Show version */ if *versionFlag == true { argsVersion() return Args{}, misc.ErrArgSuccessExit } if args.IsSet("type") == false { fmt.Println("args: 'type' option must be specified") return Args{}, misc.ErrConig } return Args{ ConfigPath: *confPath, LogFormat: LogFormat(*logformat), Input: func() *string { if args.IsSet("input") == true { return input } return nil }(), Output: func() *string { if args.IsSet("output") == true { return output } return nil }(), Cleanup: *cleanup, DBType: DBType(*dbType), }, nil } func argsHelp(args *getopt.Set) { additionalDescription := ` Additional description Tool for anonymizing PostgreSQL and MySQL databases' dump ` args.PrintUsage(os.Stdout) fmt.Println(additionalDescription) } func argsVersion() { fmt.Println(version) } ================================================ FILE: ctx/conf.go ================================================ package ctx import ( "fmt" "github.com/nixys/nxs-data-anonymizer/misc" conf "github.com/nixys/nxs-go-conf" ) type confOpts struct { LogFile string `conf:"logfile" conf_extraopts:"default=stderr"` LogLevel string `conf:"loglevel" conf_extraopts:"default=info"` Progress progressConf `conf:"progress"` Filters map[string]filterConf `conf:"filters"` Link []linkConf `conf:"link"` Security securityConf `conf:"security"` Variables map[string]variableFilterConf `conf:"variables"` MySQL *mysqlConf `conf:"mysql"` } type progressConf struct { Rhythm string `conf:"rhythm" conf_extraopts:"default=0s"` Humanize bool `conf:"humanize"` } type filterConf struct { Columns map[string]columnFilterConf `conf:"columns"` } type columnFilterConf struct { Type string `conf:"type" conf_extraopts:"default=template"` Value string `conf:"value" conf_extraopts:"required"` Unique bool `conf:"unique"` } type linkConf struct { Rule columnFilterConf `conf:"rule"` With map[string][]string `conf:"with" conf_extraopts:"required"` } type variableFilterConf struct { Type string `conf:"type" conf_extraopts:"default=template"` Value string `conf:"value" conf_extraopts:"required"` } type securityConf struct { Policy securityPolicyConf `conf:"policy"` Exceptions securityExceptionsConf `conf:"exceptions"` Defaults securityDefaultsConf `conf:"defaults"` } type securityPolicyConf struct { Tables string `conf:"tables" conf_extraopts:"default=pass"` Columns string `conf:"columns" conf_extraopts:"default=pass"` } type securityExceptionsConf struct { Tables []string `conf:"tables"` Columns []string `conf:"columns"` } type securityDefaultsConf struct { Columns map[string]columnFilterConf `conf:"columns"` Types []securityDefaultsTypeConf `conf:"types"` } type securityDefaultsTypeConf struct { Regex string `conf:"regex" conf_extraopts:"required"` Rule columnFilterConf `conf:"rule" conf_extraopts:"required"` } type mysqlConf struct { Host string `conf:"host" conf_extraopts:"required"` Port int `conf:"port" conf_extraopts:"required"` DB string `conf:"db" conf_extraopts:"required"` User string `conf:"user" conf_extraopts:"required"` Password string `conf:"password" conf_extraopts:"required"` } func confRead(confPath string) (confOpts, error) { var c confOpts err := conf.Load(&c, conf.Settings{ ConfPath: confPath, ConfType: conf.ConfigTypeYAML, UnknownDeny: true, }) if err != nil { return c, err } for _, f := range c.Filters { for _, cf := range f.Columns { if misc.ValueTypeFromString(cf.Type) == misc.ValueTypeUnknown { return c, fmt.Errorf("conf read: unknown column filter type") } } } for _, f := range c.Variables { if misc.ValueTypeFromString(f.Type) == misc.ValueTypeUnknown { return c, fmt.Errorf("conf read: unknown variable filter type") } } if misc.SecurityPolicyTablesTypeFromString(c.Security.Policy.Tables) == misc.SecurityPolicyTablesUnknown { return c, fmt.Errorf("conf read: unknown security policy tables type") } if misc.SecurityPolicyColumnsTypeFromString(c.Security.Policy.Columns) == misc.SecurityPolicyColumnsUnknown { return c, fmt.Errorf("conf read: unknown security policy columns type") } for _, cf := range c.Security.Defaults.Columns { if misc.ValueTypeFromString(cf.Type) == misc.ValueTypeUnknown { return c, fmt.Errorf("conf read: unknown default filter type") } } return c, nil } ================================================ FILE: ctx/context.go ================================================ package ctx import ( "fmt" "io" "os" "time" "github.com/nixys/nxs-data-anonymizer/interfaces" mysql_anonymize "github.com/nixys/nxs-data-anonymizer/modules/anonymizers/mysql" pgsql_anonymize "github.com/nixys/nxs-data-anonymizer/modules/anonymizers/pgsql" progressreader "github.com/nixys/nxs-data-anonymizer/modules/progress_reader" "github.com/nixys/nxs-data-anonymizer/ds/mysql" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" "github.com/sirupsen/logrus" appctx "github.com/nixys/nxs-go-appctx/v3" ) // Ctx defines application custom context type Ctx struct { Log *logrus.Logger Output io.Writer Progress progressCtx DB DBCtx Anonymizer interfaces.Anonymizer PR *progressreader.ProgressReader } type DBCtx struct { Cleanup bool Type DBType MySQL *mysql.MySQL } type DBType string const ( DBTypeMySQL DBType = "mysql" DBTypePgSQL DBType = "pgsql" ) type LogFormat string const ( LogFormatJSON LogFormat = "json" LogFormatPlain LogFormat = "plain" ) type progressCtx struct { Rhythm time.Duration Humanize bool } type SecurityCtx struct { TablePolicy misc.SecurityPolicyTablesType TableExceptions map[string]any } // Init initiates application custom context func AppCtxInit() (any, error) { var ir io.Reader c := &Ctx{} args, err := ArgsRead() if err != nil { return nil, err } conf, err := confRead(args.ConfigPath) if err != nil { tmpLogError("ctx init", err) return nil, err } c.Log, err = logInit(conf.LogFile, conf.LogLevel, args.LogFormat) if err != nil { tmpLogError("ctx init", err) return nil, err } if args.Input == nil { ir = os.Stdin } else { ir, err = os.Open(*args.Input) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init: open input file") return nil, err } } if args.Output == nil { c.Output = os.Stdout } else { c.Output, err = os.Create(*args.Output) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init: open output file") return nil, err } } c.DB = DBCtx{ Cleanup: args.Cleanup, Type: args.DBType, } // DEPRECATED: Connect to MySQL if necessary if conf.MySQL != nil { m, err := mysql.Connect(mysql.Settings{ Host: conf.MySQL.Host, Port: conf.MySQL.Port, Database: conf.MySQL.DB, User: conf.MySQL.User, Password: conf.MySQL.Password, }) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init") return nil, err } c.DB.MySQL = &m } else { if args.Cleanup == true { c.Log.WithFields(logrus.Fields{ "details": "destination database clean up was requested but connection to database doesn't specified", }).Errorf("ctx init") return nil, misc.ErrConig } } c.PR = progressreader.Init(ir) vr := func() map[string]relfilter.VariableRuleOpts { rules := make(map[string]relfilter.VariableRuleOpts) for n, f := range conf.Variables { rules[n] = relfilter.VariableRuleOpts{ Type: misc.ValueType(f.Type), Value: f.Value, } } return rules }() tr := func() map[string]map[string]relfilter.ColumnRuleOpts { tables := make(map[string]map[string]relfilter.ColumnRuleOpts) for t, cs := range conf.Filters { columns := make(map[string]relfilter.ColumnRuleOpts) for c, f := range cs.Columns { columns[c] = relfilter.ColumnRuleOpts{ Type: misc.ValueType(f.Type), Value: f.Value, Unique: f.Unique, } } tables[t] = columns } return tables }() dr := func() map[string]relfilter.ColumnRuleOpts { cc := make(map[string]relfilter.ColumnRuleOpts) for c, cf := range conf.Security.Defaults.Columns { cc[c] = relfilter.ColumnRuleOpts{ Type: misc.ValueTypeFromString(cf.Type), Value: cf.Value, Unique: cf.Unique, } } return cc }() trc := func() []relfilter.TypeRuleOpts { cc := []relfilter.TypeRuleOpts{} for _, t := range conf.Security.Defaults.Types { cc = append( cc, relfilter.TypeRuleOpts{ Selector: t.Regex, Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeFromString(t.Rule.Type), Value: t.Rule.Value, Unique: t.Rule.Unique, }, }, ) } return cc }() lnk := []relfilter.LinkOpts{} for _, l := range conf.Link { lnk = append( lnk, relfilter.LinkOpts{ Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeFromString(l.Rule.Type), Value: l.Rule.Value, Unique: l.Rule.Unique, }, With: l.With, }, ) } switch args.DBType { case DBTypeMySQL: c.Anonymizer, err = mysql_anonymize.Init( c.PR, mysql_anonymize.InitOpts{ Variables: vr, Security: mysql_anonymize.SecurityOpts{ TablesPolicy: misc.SecurityPolicyTablesType(conf.Security.Policy.Tables), ColumnsPolicy: misc.SecurityPolicyColumnsTypeFromString(conf.Security.Policy.Columns), TableExceptions: conf.Security.Exceptions.Tables, }, Rules: mysql_anonymize.RulesOpts{ TableRules: tr, DefaultRules: dr, ExceptionColumns: conf.Security.Exceptions.Columns, TypeRuleCustom: trc, }, Link: lnk, }, ) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init") return nil, err } case DBTypePgSQL: c.Anonymizer, err = pgsql_anonymize.Init( c.PR, pgsql_anonymize.InitOpts{ Variables: vr, Security: pgsql_anonymize.SecurityOpts{ TablesPolicy: misc.SecurityPolicyTablesType(conf.Security.Policy.Tables), ColumnsPolicy: misc.SecurityPolicyColumnsTypeFromString(conf.Security.Policy.Columns), TableExceptions: conf.Security.Exceptions.Tables, }, Rules: pgsql_anonymize.RulesOpts{ TableRules: tr, DefaultRules: dr, ExceptionColumns: conf.Security.Exceptions.Columns, TypeRuleCustom: trc, }, Link: lnk, }, ) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init") return nil, err } } // Progress settings c.Progress.Humanize = conf.Progress.Humanize c.Progress.Rhythm, err = time.ParseDuration(conf.Progress.Rhythm) if err != nil { c.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("ctx init") return nil, err } return c, nil } func tmpLogError(msg string, err error) { l, _ := appctx.DefaultLogInit(os.Stderr, logrus.InfoLevel, &logrus.JSONFormatter{}) l.WithFields(logrus.Fields{ "details": err, }).Errorf(msg) } func logInit(file, level string, ft LogFormat) (*logrus.Logger, error) { var ( f *os.File err error ) switch file { case "stdout": f = os.Stdout case "stderr": f = os.Stderr default: f, err = os.OpenFile(file, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { return nil, fmt.Errorf("log init: %w", err) } } // Validate log level l, err := logrus.ParseLevel(level) if err != nil { return nil, fmt.Errorf("log init: %w", err) } if ft == LogFormatPlain { return appctx.DefaultLogInit(f, l, nil) } return appctx.DefaultLogInit(f, l, &logrus.JSONFormatter{}) } ================================================ FILE: doc/examples/drop/MySQL/input.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'Wilford','Wintheiser','brett35@example.com','1981-10-14','1988-09-10 18:37:25'),(2,'Nyasia','Doyle','aracely46@example.com','2007-07-01','1980-10-28 23:57:00'),(3,'Ken','Haag','carroll.harris@example.com','2003-04-16','1997-03-14 18:41:06'),(4,'Leonor','Mann','johns.janick@example.org','1996-05-18','2010-04-12 00:38:42'),(5,'Eloisa','Ratke','lakin.ramiro@example.net','1982-07-22','1996-03-25 09:07:39'),(6,'Nikolas','Dibbert','judson33@example.com','1970-02-22','1979-03-16 10:10:12'),(7,'Kelley','Koch','kaci.koch@example.net','2013-05-01','2020-08-02 02:01:34'),(8,'Glen','Howe','jprosacco@example.net','1971-08-03','1971-01-02 14:19:52'),(9,'Geovanni','Medhurst','kutch.kylie@example.com','2011-04-20','2004-06-10 12:33:11'),(10,'Zella','Davis','hane.terrill@example.org','1991-11-07','2007-09-19 13:48:20'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (1,1,'Pariatur est in ut provident vero eligendi.','Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum.','Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea.','1975-07-07'),(2,2,'Unde est architecto est.','Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel.','Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem.','1976-05-25'),(3,3,'Dignissimos perspiciatis nobis quisquam saepe ad aut numquam.','Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum.','Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum.','1991-12-21'),(4,4,'Voluptas sint modi magnam.','Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem.','Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam.','2002-01-23'),(5,5,'Sapiente rem eos enim ullam ipsum ut.','Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam.','Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia.','2017-11-19'),(6,6,'Error quas doloremque est sunt quae.','Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis.','Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id.','1974-03-23'),(7,7,'Quo impedit quos molestiae dolorum in soluta dolores non.','Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut.','Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis.','2004-12-08'),(8,8,'Nulla quia repellendus et autem vitae provident.','Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae.','Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque.','1999-02-28'),(9,9,'Similique at quia quia ut recusandae repudiandae delectus.','Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem.','Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis.','2007-08-07'),(10,10,'Est vel aperiam ipsa quod doloremque et est et.','Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem.','Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia.','2009-07-18'),(11,1,'Sint est qui dolorem eum accusantium repudiandae.','Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa.','Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum.','2010-04-16'),(12,2,'Culpa debitis ut non sapiente voluptatem.','Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus.','Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit.','1988-12-26'),(13,3,'Ut ut rerum qui quis sed sunt.','Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni.','Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis.','2001-06-01'),(14,4,'Error inventore delectus sapiente non.','Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores.','Voluptatum id amet qui quia. Nemo nulla atque dignissimos.','1974-12-07'),(15,5,'Ut aut quo aut ea occaecati est voluptas.','Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus.','Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim.','1999-09-12'),(16,6,'Nihil ea qui sequi odit rem.','Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi.','Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut.','2003-07-28'),(17,7,'Quia accusantium deserunt suscipit.','Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi.','Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis.','2015-05-24'),(18,8,'Inventore et eaque temporibus qui aut exercitationem necessitatibus.','Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt.','Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam.','1996-02-06'),(19,9,'Et soluta consequatur porro rem corrupti.','Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et.','Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur.','2018-03-31'),(20,10,'Culpa error rerum voluptatem recusandae quae tempora.','Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia.','Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos.','2007-01-22'),(21,1,'Harum laudantium fugiat debitis atque sed.','Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae.','Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia.','1987-06-29'),(22,2,'Non architecto ut voluptas aut voluptas dolor ut.','Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel.','Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque.','1993-05-06'),(23,3,'Dolores sed hic vitae ut qui.','Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae.','Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur.','1978-09-08'),(24,4,'Deleniti distinctio eos eveniet.','Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni.','Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae.','2003-06-23'),(25,5,'Ea et asperiores odio vel sunt exercitationem.','Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est.','Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio.','1972-09-16'),(26,6,'Accusamus est sed aut minus.','Et libero in in est consequuntur. Illum distinctio doloremque quas.','Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor.','2017-03-08'),(27,7,'Et sed reprehenderit nobis sed.','Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum.','Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est.','1973-08-04'),(28,8,'Autem ullam aperiam totam assumenda quod esse.','Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea.','Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae.','2014-04-26'),(29,9,'Ad dolores amet ea nisi aut enim voluptatem.','Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla.','Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in.','2006-09-07'),(30,10,'Eos fuga at ex sapiente quasi.','Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque.','Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et.','2009-07-23'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/drop/MySQL/nxs-data-anonymizer.conf ================================================ filters: authors: columns: first_name: value: "John" last_name: value: "Smith" email: value: "JohnSmith@example.com" birthdate: value: "{{ if eq .Values.birthdate \"1981-10-14\" }}{{ drop }}{{ else }}{{ .Values.added }}{{ end }}" added: value: "2000-01-01 12:00:00" posts: columns: author_id: value: "{{ if eq .Values.author_id \"1\" }}{{ drop }}{{ else }}{{ .Values.author_id }}{{ end }}" title: value: "anon_title" description: value: "anon_description" content: value: "anon_content" date: value: "2001-01-01 12:00:00" ================================================ FILE: doc/examples/drop/MySQL/output.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (2,'John','Smith','JohnSmith@example.com','1980-10-28 23:57:00','2000-01-01 12:00:00'),(3,'John','Smith','JohnSmith@example.com','1997-03-14 18:41:06','2000-01-01 12:00:00'),(4,'John','Smith','JohnSmith@example.com','2010-04-12 00:38:42','2000-01-01 12:00:00'),(5,'John','Smith','JohnSmith@example.com','1996-03-25 09:07:39','2000-01-01 12:00:00'),(6,'John','Smith','JohnSmith@example.com','1979-03-16 10:10:12','2000-01-01 12:00:00'),(7,'John','Smith','JohnSmith@example.com','2020-08-02 02:01:34','2000-01-01 12:00:00'),(8,'John','Smith','JohnSmith@example.com','1971-01-02 14:19:52','2000-01-01 12:00:00'),(9,'John','Smith','JohnSmith@example.com','2004-06-10 12:33:11','2000-01-01 12:00:00'),(10,'John','Smith','JohnSmith@example.com','2007-09-19 13:48:20','2000-01-01 12:00:00'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (2,2,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(3,3,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(4,4,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(5,5,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(6,6,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(7,7,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(8,8,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(9,9,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(10,10,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(12,2,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(13,3,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(14,4,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(15,5,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(16,6,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(17,7,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(18,8,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(19,9,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(20,10,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(22,2,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(23,3,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(24,4,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(25,5,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(26,6,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(27,7,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(28,8,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(29,9,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'),(30,10,'anon_title','anon_description','anon_content','2001-01-01 12:00:00'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/drop/PostgreSQL/input ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 Wilford Wintheiser brett35@example.com 1981-10-14 1988-09-10 18:37:25 2 Nyasia Doyle aracely46@example.com 2007-07-01 1980-10-28 23:57:00 3 Ken Haag carroll.harris@example.com 2003-04-16 1997-03-14 18:41:06 4 Leonor Mann johns.janick@example.org 1996-05-18 2010-04-12 00:38:42 5 Eloisa Ratke lakin.ramiro@example.net 1982-07-22 1996-03-25 09:07:39 6 Nikolas Dibbert judson33@example.com 1970-02-22 1979-03-16 10:10:12 7 Kelley Koch kaci.koch@example.net 2013-05-01 2020-08-02 02:01:34 8 Glen Howe jprosacco@example.net 1971-08-03 1971-01-02 14:19:52 9 Geovanni Medhurst kutch.kylie@example.com 2011-04-20 2004-06-10 12:33:11 10 Zella Davis hane.terrill@example.org 1991-11-07 2007-09-19 13:48:20 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 1 1 Pariatur est in ut provident vero eligendi. Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum. Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea. 1975-07-07 2 2 Unde est architecto est. Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel. Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem. 1976-05-25 3 3 Dignissimos perspiciatis nobis quisquam saepe ad aut numquam. Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum. Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum. 1991-12-21 4 4 Voluptas sint modi magnam. Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem. Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam. 2002-01-23 5 5 Sapiente rem eos enim ullam ipsum ut. Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam. Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia. 2017-11-19 6 6 Error quas doloremque est sunt quae. Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis. Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id. 1974-03-23 7 7 Quo impedit quos molestiae dolorum in soluta dolores non. Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut. Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis. 2004-12-08 8 8 Nulla quia repellendus et autem vitae provident. Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae. Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque. 1999-02-28 9 9 Similique at quia quia ut recusandae repudiandae delectus. Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem. Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis. 2007-08-07 10 10 Est vel aperiam ipsa quod doloremque et est et. Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem. Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia. 2009-07-18 11 1 Sint est qui dolorem eum accusantium repudiandae. Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa. Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum. 2010-04-16 12 2 Culpa debitis ut non sapiente voluptatem. Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus. Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit. 1988-12-26 13 3 Ut ut rerum qui quis sed sunt. Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni. Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis. 2001-06-01 14 4 Error inventore delectus sapiente non. Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores. Voluptatum id amet qui quia. Nemo nulla atque dignissimos. 1974-12-07 15 5 Ut aut quo aut ea occaecati est voluptas. Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus. Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim. 1999-09-12 16 6 Nihil ea qui sequi odit rem. Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi. Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut. 2003-07-28 17 7 Quia accusantium deserunt suscipit. Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi. Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis. 2015-05-24 18 8 Inventore et eaque temporibus qui aut exercitationem necessitatibus. Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt. Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam. 1996-02-06 19 9 Et soluta consequatur porro rem corrupti. Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et. Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur. 2018-03-31 20 10 Culpa error rerum voluptatem recusandae quae tempora. Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia. Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos. 2007-01-22 21 1 Harum laudantium fugiat debitis atque sed. Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae. Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia. 1987-06-29 22 2 Non architecto ut voluptas aut voluptas dolor ut. Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel. Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque. 1993-05-06 23 3 Dolores sed hic vitae ut qui. Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae. Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur. 1978-09-08 24 4 Deleniti distinctio eos eveniet. Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni. Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae. 2003-06-23 25 5 Ea et asperiores odio vel sunt exercitationem. Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est. Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio. 1972-09-16 26 6 Accusamus est sed aut minus. Et libero in in est consequuntur. Illum distinctio doloremque quas. Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor. 2017-03-08 27 7 Et sed reprehenderit nobis sed. Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum. Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est. 1973-08-04 28 8 Autem ullam aperiam totam assumenda quod esse. Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea. Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae. 2014-04-26 29 9 Ad dolores amet ea nisi aut enim voluptatem. Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla. Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in. 2006-09-07 30 10 Eos fuga at ex sapiente quasi. Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque. Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et. 2009-07-23 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/drop/PostgreSQL/nxs-data-anonymizer.conf ================================================ filters: public.authors: columns: first_name: value: "John" last_name: value: "Smith" email: value: "JohnSmith@example.com" birthdate: value: "{{ if eq .Values.birthdate \"1981-10-14\" }}{{ drop }}{{ else }}{{ .Values.added }}{{ end }}" added: value: "2000-01-01 12:00:00" public.posts: columns: author_id: value: "{{ if eq .Values.author_id \"1\" }}{{ drop }}{{ else }}{{ .Values.author_id }}{{ end }}" title: value: "anon_title" description: value: "anon_description" content: value: "anon_content" date: value: "2001-01-01 12:00:00" ================================================ FILE: doc/examples/drop/PostgreSQL/output ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 2 John Smith JohnSmith@example.com 1980-10-28 23:57:00 2000-01-01 12:00:00 3 John Smith JohnSmith@example.com 1997-03-14 18:41:06 2000-01-01 12:00:00 4 John Smith JohnSmith@example.com 2010-04-12 00:38:42 2000-01-01 12:00:00 5 John Smith JohnSmith@example.com 1996-03-25 09:07:39 2000-01-01 12:00:00 6 John Smith JohnSmith@example.com 1979-03-16 10:10:12 2000-01-01 12:00:00 7 John Smith JohnSmith@example.com 2020-08-02 02:01:34 2000-01-01 12:00:00 8 John Smith JohnSmith@example.com 1971-01-02 14:19:52 2000-01-01 12:00:00 9 John Smith JohnSmith@example.com 2004-06-10 12:33:11 2000-01-01 12:00:00 10 John Smith JohnSmith@example.com 2007-09-19 13:48:20 2000-01-01 12:00:00 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 2 2 anon_title anon_description anon_content 2001-01-01 12:00:00 3 3 anon_title anon_description anon_content 2001-01-01 12:00:00 4 4 anon_title anon_description anon_content 2001-01-01 12:00:00 5 5 anon_title anon_description anon_content 2001-01-01 12:00:00 6 6 anon_title anon_description anon_content 2001-01-01 12:00:00 7 7 anon_title anon_description anon_content 2001-01-01 12:00:00 8 8 anon_title anon_description anon_content 2001-01-01 12:00:00 9 9 anon_title anon_description anon_content 2001-01-01 12:00:00 10 10 anon_title anon_description anon_content 2001-01-01 12:00:00 12 2 anon_title anon_description anon_content 2001-01-01 12:00:00 13 3 anon_title anon_description anon_content 2001-01-01 12:00:00 14 4 anon_title anon_description anon_content 2001-01-01 12:00:00 15 5 anon_title anon_description anon_content 2001-01-01 12:00:00 16 6 anon_title anon_description anon_content 2001-01-01 12:00:00 17 7 anon_title anon_description anon_content 2001-01-01 12:00:00 18 8 anon_title anon_description anon_content 2001-01-01 12:00:00 19 9 anon_title anon_description anon_content 2001-01-01 12:00:00 20 10 anon_title anon_description anon_content 2001-01-01 12:00:00 22 2 anon_title anon_description anon_content 2001-01-01 12:00:00 23 3 anon_title anon_description anon_content 2001-01-01 12:00:00 24 4 anon_title anon_description anon_content 2001-01-01 12:00:00 25 5 anon_title anon_description anon_content 2001-01-01 12:00:00 26 6 anon_title anon_description anon_content 2001-01-01 12:00:00 27 7 anon_title anon_description anon_content 2001-01-01 12:00:00 28 8 anon_title anon_description anon_content 2001-01-01 12:00:00 29 9 anon_title anon_description anon_content 2001-01-01 12:00:00 30 10 anon_title anon_description anon_content 2001-01-01 12:00:00 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/drop/Readme.md ================================================ # Example `variables` An example of using nxs-data-anonymizer in a simple configuration with filters and variables blocks. In order to use variables in the "filters" block, you need to describe the "variables" block: ```yaml variables: some_variable: # Variable name value: "some_value" # Variable value ``` If you use a function to generate a value, then in this block it will be executed once and the resulting value will be the same for all its occurrences in the dump. An example of a configuration: ```yaml variables: var1: value: "" var2: value: "" var3: value: "" filters: table1: columns: table1_col1: value: "" table1_col2: value: "{{ .Variables.var1 }}" table1_col3: value: "{{ .Variables.var2 }}" table2: columns: table2_col1: value: "" table2_col2: value: "{{ .Variables.var1 }}" table2_col3: value: "{{ .Variables.var3 }}" ``` Working examples of configurations in the `./MySQL` and `./PostgreSQL` directories. ================================================ FILE: doc/examples/filters/MySQL/input.sql ================================================ -- MySQL dump 10.13 Distrib 8.1.0, for Linux (x86_64) -- -- Host: localhost Database: test_db -- ------------------------------------------------------ -- Server version 8.1.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `test_tbl` -- DROP TABLE IF EXISTS `test_tbl`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `test_tbl` ( `int_count` int NOT NULL, `int_type` int DEFAULT NULL, `dbl_type` double DEFAULT NULL, `vchar_type` varchar(255) DEFAULT NULL, `date_type` date DEFAULT NULL, `time_type` time DEFAULT NULL, PRIMARY KEY (`int_count`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `test_tbl` -- LOCK TABLES `test_tbl` WRITE; /*!40000 ALTER TABLE `test_tbl` DISABLE KEYS */; INSERT INTO `test_tbl` VALUES (1,1,1.1,'aaaaaa',NULL,NULL),(2,2,2.2,'bbbbbb',NULL,NULL),(3,3,3.3,'cccccc',NULL,NULL),(4,4,4.4,'dddddd',NULL,NULL),(5,5,5.5,'eeeeee',NULL,NULL); /*!40000 ALTER TABLE `test_tbl` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2023-08-18 6:52:42 ================================================ FILE: doc/examples/filters/MySQL/nxs-data-anonymizer.conf ================================================ filters: test_tbl: columns: int_type: value: "1" dbl_type: value: "99.999" vchar_type: value: "anon-data" date_type: value: "2001-01-01" time_type: value: "20:20:20" ================================================ FILE: doc/examples/filters/MySQL/output.sql ================================================ -- MySQL dump 10.13 Distrib 8.1.0, for Linux (x86_64) -- -- Host: localhost Database: test_db -- ------------------------------------------------------ -- Server version 8.1.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `test_tbl` -- DROP TABLE IF EXISTS `test_tbl`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `test_tbl` ( `int_count` int NOT NULL, `int_type` int DEFAULT NULL, `dbl_type` double DEFAULT NULL, `vchar_type` varchar(255) DEFAULT NULL, `date_type` date DEFAULT NULL, `time_type` time DEFAULT NULL, PRIMARY KEY (`int_count`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `test_tbl` -- LOCK TABLES `test_tbl` WRITE; /*!40000 ALTER TABLE `test_tbl` DISABLE KEYS */; INSERT INTO `test_tbl` VALUES (1,1,99.999,'anon-data','2001-01-01','20:20:20'),(2,1,99.999,'anon-data','2001-01-01','20:20:20'),(3,1,99.999,'anon-data','2001-01-01','20:20:20'),(4,1,99.999,'anon-data','2001-01-01','20:20:20'),(5,1,99.999,'anon-data','2001-01-01','20:20:20'); /*!40000 ALTER TABLE `test_tbl` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2023-08-18 6:52:42 ================================================ FILE: doc/examples/filters/PostgreSQL/input ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.1 (Debian 16.1-1.pgdg120+1) -- Dumped by pg_dump version 16.1 (Debian 16.1-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; \N 42.99465 \N Biba \N \N 19:51:50+00 \N \N \N 6 \N -84.46685 \N Pupa \N \N 03:34:36+00 \N \N \N 2 \N 72.52040 \N Lupa \N 15:17:37+00 t \N \N 4 \N 99.37111 \N Boba \N 03:34:36+00 \N \N \N 8 \N -90.90125 \N Cerebla \N \N 22:00:45+00 \N \N \N 10 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/filters/PostgreSQL/nxs-data-anonymizer.conf ================================================ filters: public.list_types: columns: integer_type: value: "{{ if (isNull .Values.integer_type) }}{{ 0 }}{{ else }}{{ 123 }}{{ end }}" numeric_type: value: "{{ if (isNull .Values.numeric_type) }}{{ 0 }}{{ else }}{{ 1.23 }}{{ end }}" double_precision_type: value: "{{ if (isNull .Values.double_precision_type) }}{{ 10 }}{{ else }}{{ 321 }}{{ end }}" varchar_type: value: "anon_text" text_type: value: "random text" date_type: value: "01-01-2000" time_tz_type: value: "20:20:20" boolean_type: value: "{{ if (isNull .Values.boolean_type) }}{{ false }}{{ else }}{{ true }}{{ end }}" xml_type: value: "random_xml" jsonb_type: value: "null" varchar_mass_type: value: "{esd,lfg,dil}" integer_mass_type: value: "{{`{{4,5,6},{4,5,6}}`}}" double_mass_type: value: "{{`{{{0.1,0.2,0.3},{0.1,0.2,0.3}},{{0.1,0.2,0.3},{0.1,0.2,0.3}}}`}}" ================================================ FILE: doc/examples/filters/PostgreSQL/output ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.1 (Debian 16.1-1.pgdg120+1) -- Dumped by pg_dump version 16.1 (Debian 16.1-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 6 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 2 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 4 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 8 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 10 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 1 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 3 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 9 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 5 123 1.23 321 anon_text random text 01-01-2000 20:20:20 true random_xml null 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/filters/Readme.md ================================================ # Example `filters` An example of using nxs-data-anonymizer in a simple configuration with one filters block. All that needs to be specified in the configuration file is a list of tables to be processed with a list of replacement rules for the columns that need to be changed. An example of a configuration: ```yaml filters: table1: # Table name to process. columns: table1_col1: # Column name to process. value: "{{ - value_generation_function - }}" # Value for substitution. unique: true # The unique values ​​flag, default "false", is used only with the value generation function. table1_col2: value: "" table1_col3: value: "" table2: columns: table2_col1: value: "{{ - value_generation_function - }}" unique: true table2_col2: value: "" table2_col3: value: "" ``` Working examples of configurations in the `./MySQL` and `./PostgreSQL` directories. ================================================ FILE: doc/examples/links/MySQL/input.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'Wilford','Wintheiser','brett35@example.com','1981-10-14','1988-09-10 18:37:25'),(2,'Nyasia','Doyle','aracely46@example.com','2007-07-01','1980-10-28 23:57:00'),(3,'Ken','Haag','carroll.harris@example.com','2003-04-16','1997-03-14 18:41:06'),(4,'Leonor','Mann','johns.janick@example.org','1996-05-18','2010-04-12 00:38:42'),(5,'Eloisa','Ratke','lakin.ramiro@example.net','1982-07-22','1996-03-25 09:07:39'),(6,'Nikolas','Dibbert','judson33@example.com','1970-02-22','1979-03-16 10:10:12'),(7,'Kelley','Koch','kaci.koch@example.net','2013-05-01','2020-08-02 02:01:34'),(8,'Glen','Howe','jprosacco@example.net','1971-08-03','1971-01-02 14:19:52'),(9,'Geovanni','Medhurst','kutch.kylie@example.com','2011-04-20','2004-06-10 12:33:11'),(10,'Zella','Davis','hane.terrill@example.org','1991-11-07','2007-09-19 13:48:20'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (1,1,'Pariatur est in ut provident vero eligendi.','Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum.','Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea.','1975-07-07'),(2,2,'Unde est architecto est.','Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel.','Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem.','1976-05-25'),(3,3,'Dignissimos perspiciatis nobis quisquam saepe ad aut numquam.','Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum.','Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum.','1991-12-21'),(4,4,'Voluptas sint modi magnam.','Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem.','Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam.','2002-01-23'),(5,5,'Sapiente rem eos enim ullam ipsum ut.','Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam.','Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia.','2017-11-19'),(6,6,'Error quas doloremque est sunt quae.','Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis.','Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id.','1974-03-23'),(7,7,'Quo impedit quos molestiae dolorum in soluta dolores non.','Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut.','Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis.','2004-12-08'),(8,8,'Nulla quia repellendus et autem vitae provident.','Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae.','Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque.','1999-02-28'),(9,9,'Similique at quia quia ut recusandae repudiandae delectus.','Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem.','Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis.','2007-08-07'),(10,10,'Est vel aperiam ipsa quod doloremque et est et.','Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem.','Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia.','2009-07-18'),(11,1,'Sint est qui dolorem eum accusantium repudiandae.','Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa.','Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum.','2010-04-16'),(12,2,'Culpa debitis ut non sapiente voluptatem.','Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus.','Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit.','1988-12-26'),(13,3,'Ut ut rerum qui quis sed sunt.','Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni.','Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis.','2001-06-01'),(14,4,'Error inventore delectus sapiente non.','Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores.','Voluptatum id amet qui quia. Nemo nulla atque dignissimos.','1974-12-07'),(15,5,'Ut aut quo aut ea occaecati est voluptas.','Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus.','Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim.','1999-09-12'),(16,6,'Nihil ea qui sequi odit rem.','Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi.','Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut.','2003-07-28'),(17,7,'Quia accusantium deserunt suscipit.','Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi.','Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis.','2015-05-24'),(18,8,'Inventore et eaque temporibus qui aut exercitationem necessitatibus.','Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt.','Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam.','1996-02-06'),(19,9,'Et soluta consequatur porro rem corrupti.','Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et.','Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur.','2018-03-31'),(20,10,'Culpa error rerum voluptatem recusandae quae tempora.','Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia.','Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos.','2007-01-22'),(21,1,'Harum laudantium fugiat debitis atque sed.','Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae.','Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia.','1987-06-29'),(22,2,'Non architecto ut voluptas aut voluptas dolor ut.','Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel.','Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque.','1993-05-06'),(23,3,'Dolores sed hic vitae ut qui.','Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae.','Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur.','1978-09-08'),(24,4,'Deleniti distinctio eos eveniet.','Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni.','Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae.','2003-06-23'),(25,5,'Ea et asperiores odio vel sunt exercitationem.','Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est.','Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio.','1972-09-16'),(26,6,'Accusamus est sed aut minus.','Et libero in in est consequuntur. Illum distinctio doloremque quas.','Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor.','2017-03-08'),(27,7,'Et sed reprehenderit nobis sed.','Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum.','Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est.','1973-08-04'),(28,8,'Autem ullam aperiam totam assumenda quod esse.','Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea.','Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae.','2014-04-26'),(29,9,'Ad dolores amet ea nisi aut enim voluptatem.','Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla.','Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in.','2006-09-07'),(30,10,'Eos fuga at ex sapiente quasi.','Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque.','Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et.','2009-07-23'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/links/MySQL/nxs-data-anonymizer.conf ================================================ link: - rule: value: "{{ randInt 1 50 }}" unique: true with: authors: - id posts: - author_id filters: authors: columns: first_name: value: "{{- randAlphaNum 20 -}}" last_name: value: "{{- randAlphaNum 20 -}}" birthdate: value: "1999-12-31" added: value: "2000-01-01 12:00:00" posts: columns: id: value: "{{ randInt 1 100 }}" unique: true ================================================ FILE: doc/examples/links/MySQL/output.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (26,'lwjNB8ofmQjcmzIKx23U','pBfm9pHABWxqgVMNk1pY','brett35@example.com','1999-12-31','2000-01-01 12:00:00'),(48,'xtc5AqJUOuAGGBir1Gvn','zdi0Y2ntYLIdTMGBhsRd','aracely46@example.com','1999-12-31','2000-01-01 12:00:00'),(9,'719GkwVKuXEKjAAohgrk','jU68LcKRCwZ3yFAOsQws','carroll.harris@example.com','1999-12-31','2000-01-01 12:00:00'),(15,'Bcync5tDYRvDOad9ulHY','70FuTHdJ2diuXKn5FLUl','johns.janick@example.org','1999-12-31','2000-01-01 12:00:00'),(49,'JsRPcdhoD7eUSG2yqaln','LR33Yhxv4bs2LdcvhTvg','lakin.ramiro@example.net','1999-12-31','2000-01-01 12:00:00'),(10,'jckw1fZr214qyZk2N5qd','Dx1dlwV6M9bownRFj8jv','judson33@example.com','1999-12-31','2000-01-01 12:00:00'),(46,'LynAXGoDTGMsFWxjggUr','mW9QmnaWOWeG0uTR3y4v','kaci.koch@example.net','1999-12-31','2000-01-01 12:00:00'),(8,'ZhCmwfvwrOmSTKN9vXrw','MuUlp8h02AyIQapcTNid','jprosacco@example.net','1999-12-31','2000-01-01 12:00:00'),(18,'04b4LKxXcOioU5JkO6Iy','SBoyCTw1RCtx0rMp6qJ7','kutch.kylie@example.com','1999-12-31','2000-01-01 12:00:00'),(42,'21L1p5ixBhOvI3P3iF5F','xsRxqdLYqLIGpdpNYrNA','hane.terrill@example.org','1999-12-31','2000-01-01 12:00:00'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (89,26,'Pariatur est in ut provident vero eligendi.','Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum.','Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea.','1975-07-07'),(5,48,'Unde est architecto est.','Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel.','Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem.','1976-05-25'),(56,9,'Dignissimos perspiciatis nobis quisquam saepe ad aut numquam.','Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum.','Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum.','1991-12-21'),(46,15,'Voluptas sint modi magnam.','Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem.','Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam.','2002-01-23'),(76,49,'Sapiente rem eos enim ullam ipsum ut.','Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam.','Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia.','2017-11-19'),(99,10,'Error quas doloremque est sunt quae.','Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis.','Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id.','1974-03-23'),(13,46,'Quo impedit quos molestiae dolorum in soluta dolores non.','Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut.','Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis.','2004-12-08'),(42,8,'Nulla quia repellendus et autem vitae provident.','Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae.','Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque.','1999-02-28'),(61,18,'Similique at quia quia ut recusandae repudiandae delectus.','Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem.','Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis.','2007-08-07'),(11,42,'Est vel aperiam ipsa quod doloremque et est et.','Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem.','Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia.','2009-07-18'),(87,26,'Sint est qui dolorem eum accusantium repudiandae.','Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa.','Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum.','2010-04-16'),(4,48,'Culpa debitis ut non sapiente voluptatem.','Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus.','Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit.','1988-12-26'),(95,9,'Ut ut rerum qui quis sed sunt.','Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni.','Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis.','2001-06-01'),(52,15,'Error inventore delectus sapiente non.','Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores.','Voluptatum id amet qui quia. Nemo nulla atque dignissimos.','1974-12-07'),(49,49,'Ut aut quo aut ea occaecati est voluptas.','Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus.','Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim.','1999-09-12'),(82,10,'Nihil ea qui sequi odit rem.','Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi.','Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut.','2003-07-28'),(40,46,'Quia accusantium deserunt suscipit.','Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi.','Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis.','2015-05-24'),(28,8,'Inventore et eaque temporibus qui aut exercitationem necessitatibus.','Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt.','Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam.','1996-02-06'),(90,18,'Et soluta consequatur porro rem corrupti.','Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et.','Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur.','2018-03-31'),(36,42,'Culpa error rerum voluptatem recusandae quae tempora.','Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia.','Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos.','2007-01-22'),(9,26,'Harum laudantium fugiat debitis atque sed.','Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae.','Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia.','1987-06-29'),(77,48,'Non architecto ut voluptas aut voluptas dolor ut.','Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel.','Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque.','1993-05-06'),(18,9,'Dolores sed hic vitae ut qui.','Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae.','Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur.','1978-09-08'),(29,15,'Deleniti distinctio eos eveniet.','Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni.','Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae.','2003-06-23'),(80,49,'Ea et asperiores odio vel sunt exercitationem.','Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est.','Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio.','1972-09-16'),(69,10,'Accusamus est sed aut minus.','Et libero in in est consequuntur. Illum distinctio doloremque quas.','Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor.','2017-03-08'),(98,46,'Et sed reprehenderit nobis sed.','Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum.','Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est.','1973-08-04'),(27,8,'Autem ullam aperiam totam assumenda quod esse.','Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea.','Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae.','2014-04-26'),(64,18,'Ad dolores amet ea nisi aut enim voluptatem.','Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla.','Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in.','2006-09-07'),(32,42,'Eos fuga at ex sapiente quasi.','Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque.','Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et.','2009-07-23'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/links/PostgreSQL/input ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 Wilford Wintheiser brett35@example.com 1981-10-14 1988-09-10 18:37:25 2 Nyasia Doyle aracely46@example.com 2007-07-01 1980-10-28 23:57:00 3 Ken Haag carroll.harris@example.com 2003-04-16 1997-03-14 18:41:06 4 Leonor Mann johns.janick@example.org 1996-05-18 2010-04-12 00:38:42 5 Eloisa Ratke lakin.ramiro@example.net 1982-07-22 1996-03-25 09:07:39 6 Nikolas Dibbert judson33@example.com 1970-02-22 1979-03-16 10:10:12 7 Kelley Koch kaci.koch@example.net 2013-05-01 2020-08-02 02:01:34 8 Glen Howe jprosacco@example.net 1971-08-03 1971-01-02 14:19:52 9 Geovanni Medhurst kutch.kylie@example.com 2011-04-20 2004-06-10 12:33:11 10 Zella Davis hane.terrill@example.org 1991-11-07 2007-09-19 13:48:20 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 1 1 Pariatur est in ut provident vero eligendi. Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum. Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea. 1975-07-07 2 2 Unde est architecto est. Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel. Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem. 1976-05-25 3 3 Dignissimos perspiciatis nobis quisquam saepe ad aut numquam. Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum. Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum. 1991-12-21 4 4 Voluptas sint modi magnam. Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem. Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam. 2002-01-23 5 5 Sapiente rem eos enim ullam ipsum ut. Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam. Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia. 2017-11-19 6 6 Error quas doloremque est sunt quae. Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis. Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id. 1974-03-23 7 7 Quo impedit quos molestiae dolorum in soluta dolores non. Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut. Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis. 2004-12-08 8 8 Nulla quia repellendus et autem vitae provident. Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae. Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque. 1999-02-28 9 9 Similique at quia quia ut recusandae repudiandae delectus. Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem. Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis. 2007-08-07 10 10 Est vel aperiam ipsa quod doloremque et est et. Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem. Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia. 2009-07-18 11 1 Sint est qui dolorem eum accusantium repudiandae. Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa. Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum. 2010-04-16 12 2 Culpa debitis ut non sapiente voluptatem. Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus. Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit. 1988-12-26 13 3 Ut ut rerum qui quis sed sunt. Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni. Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis. 2001-06-01 14 4 Error inventore delectus sapiente non. Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores. Voluptatum id amet qui quia. Nemo nulla atque dignissimos. 1974-12-07 15 5 Ut aut quo aut ea occaecati est voluptas. Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus. Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim. 1999-09-12 16 6 Nihil ea qui sequi odit rem. Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi. Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut. 2003-07-28 17 7 Quia accusantium deserunt suscipit. Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi. Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis. 2015-05-24 18 8 Inventore et eaque temporibus qui aut exercitationem necessitatibus. Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt. Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam. 1996-02-06 19 9 Et soluta consequatur porro rem corrupti. Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et. Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur. 2018-03-31 20 10 Culpa error rerum voluptatem recusandae quae tempora. Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia. Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos. 2007-01-22 21 1 Harum laudantium fugiat debitis atque sed. Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae. Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia. 1987-06-29 22 2 Non architecto ut voluptas aut voluptas dolor ut. Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel. Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque. 1993-05-06 23 3 Dolores sed hic vitae ut qui. Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae. Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur. 1978-09-08 24 4 Deleniti distinctio eos eveniet. Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni. Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae. 2003-06-23 25 5 Ea et asperiores odio vel sunt exercitationem. Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est. Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio. 1972-09-16 26 6 Accusamus est sed aut minus. Et libero in in est consequuntur. Illum distinctio doloremque quas. Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor. 2017-03-08 27 7 Et sed reprehenderit nobis sed. Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum. Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est. 1973-08-04 28 8 Autem ullam aperiam totam assumenda quod esse. Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea. Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae. 2014-04-26 29 9 Ad dolores amet ea nisi aut enim voluptatem. Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla. Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in. 2006-09-07 30 10 Eos fuga at ex sapiente quasi. Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque. Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et. 2009-07-23 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/links/PostgreSQL/nxs-data-anonymizer.conf ================================================ link: - rule: value: "{{ randInt 1 50 }}" unique: true with: public.authors: - id public.posts: - author_id filters: public.authors: columns: first_name: value: "{{- randAlphaNum 20 -}}" last_name: value: "{{- randAlphaNum 20 -}}" birthdate: value: "1999-12-31" added: value: "2000-01-01 12:00:00" public.posts: columns: id: value: "{{ randInt 1 100 }}" unique: true ================================================ FILE: doc/examples/links/PostgreSQL/output ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 23 35sXOxBxUPRVA0NnIIZq 6eurfFlAsmrwlshZ9lBO brett35@example.com 1999-12-31 2000-01-01 12:00:00 19 5nBuYvwvvwHmCMPA80ui NhCGMK31icSCJjXJjfCj aracely46@example.com 1999-12-31 2000-01-01 12:00:00 10 f6R0k3DQr9GWGSqjhQZZ ep3asHE3WfCICDoeHiuw carroll.harris@example.com 1999-12-31 2000-01-01 12:00:00 36 6nenSS75QXj0FjujvehB iNGLlJWPeEzewRAmVq06 johns.janick@example.org 1999-12-31 2000-01-01 12:00:00 17 GJsk4D80CbJGJREN1Vub HLzLFc3lmD3jCWh9h0QV lakin.ramiro@example.net 1999-12-31 2000-01-01 12:00:00 42 1FkGPmdU0PLYg9S33ZsB U6kT2W9bYV1An8MWTux6 judson33@example.com 1999-12-31 2000-01-01 12:00:00 39 OEzarFYC58fr4RQGQ7mm csA3jA009Q1wH6AJaq4q kaci.koch@example.net 1999-12-31 2000-01-01 12:00:00 37 UaNlog7FzeYvEufa4LEb CPr3R2HG3SvH5FCHUeht jprosacco@example.net 1999-12-31 2000-01-01 12:00:00 9 6VJrbHj1s3O87C6rcjGj ATUdQe47dfexdIq6YjVs kutch.kylie@example.com 1999-12-31 2000-01-01 12:00:00 35 vdu1dbX34myf6S2wAYhG 292VinyFnt8MTThIYwk4 hane.terrill@example.org 1999-12-31 2000-01-01 12:00:00 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 52 23 Pariatur est in ut provident vero eligendi. Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum. Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea. 1975-07-07 88 19 Unde est architecto est. Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel. Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem. 1976-05-25 96 10 Dignissimos perspiciatis nobis quisquam saepe ad aut numquam. Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum. Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum. 1991-12-21 71 36 Voluptas sint modi magnam. Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem. Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam. 2002-01-23 25 17 Sapiente rem eos enim ullam ipsum ut. Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam. Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia. 2017-11-19 43 42 Error quas doloremque est sunt quae. Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis. Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id. 1974-03-23 11 39 Quo impedit quos molestiae dolorum in soluta dolores non. Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut. Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis. 2004-12-08 4 37 Nulla quia repellendus et autem vitae provident. Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae. Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque. 1999-02-28 85 9 Similique at quia quia ut recusandae repudiandae delectus. Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem. Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis. 2007-08-07 15 35 Est vel aperiam ipsa quod doloremque et est et. Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem. Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia. 2009-07-18 22 23 Sint est qui dolorem eum accusantium repudiandae. Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa. Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum. 2010-04-16 17 19 Culpa debitis ut non sapiente voluptatem. Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus. Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit. 1988-12-26 61 10 Ut ut rerum qui quis sed sunt. Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni. Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis. 2001-06-01 5 36 Error inventore delectus sapiente non. Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores. Voluptatum id amet qui quia. Nemo nulla atque dignissimos. 1974-12-07 24 17 Ut aut quo aut ea occaecati est voluptas. Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus. Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim. 1999-09-12 68 42 Nihil ea qui sequi odit rem. Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi. Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut. 2003-07-28 82 39 Quia accusantium deserunt suscipit. Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi. Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis. 2015-05-24 65 37 Inventore et eaque temporibus qui aut exercitationem necessitatibus. Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt. Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam. 1996-02-06 70 9 Et soluta consequatur porro rem corrupti. Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et. Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur. 2018-03-31 10 35 Culpa error rerum voluptatem recusandae quae tempora. Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia. Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos. 2007-01-22 51 23 Harum laudantium fugiat debitis atque sed. Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae. Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia. 1987-06-29 57 19 Non architecto ut voluptas aut voluptas dolor ut. Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel. Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque. 1993-05-06 31 10 Dolores sed hic vitae ut qui. Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae. Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur. 1978-09-08 72 36 Deleniti distinctio eos eveniet. Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni. Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae. 2003-06-23 54 17 Ea et asperiores odio vel sunt exercitationem. Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est. Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio. 1972-09-16 75 42 Accusamus est sed aut minus. Et libero in in est consequuntur. Illum distinctio doloremque quas. Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor. 2017-03-08 39 39 Et sed reprehenderit nobis sed. Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum. Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est. 1973-08-04 47 37 Autem ullam aperiam totam assumenda quod esse. Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea. Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae. 2014-04-26 66 9 Ad dolores amet ea nisi aut enim voluptatem. Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla. Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in. 2006-09-07 32 35 Eos fuga at ex sapiente quasi. Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque. Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et. 2009-07-23 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/links/Readme.md ================================================ # Example `variables` An example of using nxs-data-anonymizer in a simple configuration with filters and link blocks. Configuration block description: ```yaml link: - rule: # Description of the value generation rule. value: "some_value_generator" # Some function for generating values ​​with given parameters. unique: true # Flag of uniqueness of the value. with: # Description of tables with fields for which value coherence must be maintained. some_table1: - id some_table2: - id_from_table1 ``` An example of a configuration: ```yaml link: - rule: value: "" unique: true with: table1: - col1_linked table2: - col2_linked filters: table1: columns: col2: value: "" col3: value: "" table2: columns: col1: value: "" col3: value: "" ``` Working examples of configurations in the `./MySQL` and `./PostgreSQL` directories. ================================================ FILE: doc/examples/security/MySQL/input.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'Wilford','Wintheiser','brett35@example.com','1981-10-14','1988-09-10 18:37:25'),(2,'Nyasia','Doyle','aracely46@example.com','2007-07-01','1980-10-28 23:57:00'),(3,'Ken','Haag','carroll.harris@example.com','2003-04-16','1997-03-14 18:41:06'),(4,'Leonor','Mann','johns.janick@example.org','1996-05-18','2010-04-12 00:38:42'),(5,'Eloisa','Ratke','lakin.ramiro@example.net','1982-07-22','1996-03-25 09:07:39'),(6,'Nikolas','Dibbert','judson33@example.com','1970-02-22','1979-03-16 10:10:12'),(7,'Kelley','Koch','kaci.koch@example.net','2013-05-01','2020-08-02 02:01:34'),(8,'Glen','Howe','jprosacco@example.net','1971-08-03','1971-01-02 14:19:52'),(9,'Geovanni','Medhurst','kutch.kylie@example.com','2011-04-20','2004-06-10 12:33:11'),(10,'Zella','Davis','hane.terrill@example.org','1991-11-07','2007-09-19 13:48:20'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (1,1,'Pariatur est in ut provident vero eligendi.','Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum.','Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea.','1975-07-07'),(2,2,'Unde est architecto est.','Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel.','Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem.','1976-05-25'),(3,3,'Dignissimos perspiciatis nobis quisquam saepe ad aut numquam.','Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum.','Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum.','1991-12-21'),(4,4,'Voluptas sint modi magnam.','Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem.','Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam.','2002-01-23'),(5,5,'Sapiente rem eos enim ullam ipsum ut.','Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam.','Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia.','2017-11-19'),(6,6,'Error quas doloremque est sunt quae.','Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis.','Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id.','1974-03-23'),(7,7,'Quo impedit quos molestiae dolorum in soluta dolores non.','Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut.','Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis.','2004-12-08'),(8,8,'Nulla quia repellendus et autem vitae provident.','Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae.','Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque.','1999-02-28'),(9,9,'Similique at quia quia ut recusandae repudiandae delectus.','Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem.','Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis.','2007-08-07'),(10,10,'Est vel aperiam ipsa quod doloremque et est et.','Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem.','Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia.','2009-07-18'),(11,1,'Sint est qui dolorem eum accusantium repudiandae.','Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa.','Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum.','2010-04-16'),(12,2,'Culpa debitis ut non sapiente voluptatem.','Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus.','Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit.','1988-12-26'),(13,3,'Ut ut rerum qui quis sed sunt.','Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni.','Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis.','2001-06-01'),(14,4,'Error inventore delectus sapiente non.','Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores.','Voluptatum id amet qui quia. Nemo nulla atque dignissimos.','1974-12-07'),(15,5,'Ut aut quo aut ea occaecati est voluptas.','Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus.','Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim.','1999-09-12'),(16,6,'Nihil ea qui sequi odit rem.','Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi.','Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut.','2003-07-28'),(17,7,'Quia accusantium deserunt suscipit.','Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi.','Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis.','2015-05-24'),(18,8,'Inventore et eaque temporibus qui aut exercitationem necessitatibus.','Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt.','Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam.','1996-02-06'),(19,9,'Et soluta consequatur porro rem corrupti.','Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et.','Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur.','2018-03-31'),(20,10,'Culpa error rerum voluptatem recusandae quae tempora.','Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia.','Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos.','2007-01-22'),(21,1,'Harum laudantium fugiat debitis atque sed.','Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae.','Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia.','1987-06-29'),(22,2,'Non architecto ut voluptas aut voluptas dolor ut.','Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel.','Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque.','1993-05-06'),(23,3,'Dolores sed hic vitae ut qui.','Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae.','Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur.','1978-09-08'),(24,4,'Deleniti distinctio eos eveniet.','Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni.','Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae.','2003-06-23'),(25,5,'Ea et asperiores odio vel sunt exercitationem.','Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est.','Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio.','1972-09-16'),(26,6,'Accusamus est sed aut minus.','Et libero in in est consequuntur. Illum distinctio doloremque quas.','Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor.','2017-03-08'),(27,7,'Et sed reprehenderit nobis sed.','Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum.','Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est.','1973-08-04'),(28,8,'Autem ullam aperiam totam assumenda quod esse.','Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea.','Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae.','2014-04-26'),(29,9,'Ad dolores amet ea nisi aut enim voluptatem.','Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla.','Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in.','2006-09-07'),(30,10,'Eos fuga at ex sapiente quasi.','Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque.','Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et.','2009-07-23'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/security/MySQL/nxs-data-anonymizer.conf ================================================ security: policy: tables: skip columns: randomize exceptions: columns: - email - id defaults: columns: birthdate: value: "1999-12-31" filters: authors: columns: first_name: value: "{{- randAlphaNum 20 -}}" added: value: "2000-01-01 12:00:00" ================================================ FILE: doc/examples/security/MySQL/output.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'1l03v4S3kULe9MT504eo','randomized varchar','brett35@example.com','1999-12-31','2000-01-01 12:00:00'),(2,'qQOaG6T57jIUbjFswSZY','randomized varchar','aracely46@example.com','1999-12-31','2000-01-01 12:00:00'),(3,'r5INLGwas75FRG8HlxIH','randomized varchar','carroll.harris@example.com','1999-12-31','2000-01-01 12:00:00'),(4,'RQ8g1cPBpGlDBXozyOCS','randomized varchar','johns.janick@example.org','1999-12-31','2000-01-01 12:00:00'),(5,'d2sJnwtCGDAeBUszVtnS','randomized varchar','lakin.ramiro@example.net','1999-12-31','2000-01-01 12:00:00'),(6,'rTJerd760gdClROJjVAe','randomized varchar','judson33@example.com','1999-12-31','2000-01-01 12:00:00'),(7,'RMsGEydALqtyaTPBKsp9','randomized varchar','kaci.koch@example.net','1999-12-31','2000-01-01 12:00:00'),(8,'bmz2gTMJRYF4HHPn2wiu','randomized varchar','jprosacco@example.net','1999-12-31','2000-01-01 12:00:00'),(9,'ifxehp3b3jrbafETxeab','randomized varchar','kutch.kylie@example.com','1999-12-31','2000-01-01 12:00:00'),(10,'tAbuLmPP94Z41b1Pp5SZ','randomized varchar','hane.terrill@example.org','1999-12-31','2000-01-01 12:00:00'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/security/PostgreSQL/input ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 Wilford Wintheiser brett35@example.com 1981-10-14 1988-09-10 18:37:25 2 Nyasia Doyle aracely46@example.com 2007-07-01 1980-10-28 23:57:00 3 Ken Haag carroll.harris@example.com 2003-04-16 1997-03-14 18:41:06 4 Leonor Mann johns.janick@example.org 1996-05-18 2010-04-12 00:38:42 5 Eloisa Ratke lakin.ramiro@example.net 1982-07-22 1996-03-25 09:07:39 6 Nikolas Dibbert judson33@example.com 1970-02-22 1979-03-16 10:10:12 7 Kelley Koch kaci.koch@example.net 2013-05-01 2020-08-02 02:01:34 8 Glen Howe jprosacco@example.net 1971-08-03 1971-01-02 14:19:52 9 Geovanni Medhurst kutch.kylie@example.com 2011-04-20 2004-06-10 12:33:11 10 Zella Davis hane.terrill@example.org 1991-11-07 2007-09-19 13:48:20 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 1 1 Pariatur est in ut provident vero eligendi. Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum. Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea. 1975-07-07 2 2 Unde est architecto est. Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel. Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem. 1976-05-25 3 3 Dignissimos perspiciatis nobis quisquam saepe ad aut numquam. Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum. Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum. 1991-12-21 4 4 Voluptas sint modi magnam. Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem. Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam. 2002-01-23 5 5 Sapiente rem eos enim ullam ipsum ut. Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam. Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia. 2017-11-19 6 6 Error quas doloremque est sunt quae. Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis. Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id. 1974-03-23 7 7 Quo impedit quos molestiae dolorum in soluta dolores non. Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut. Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis. 2004-12-08 8 8 Nulla quia repellendus et autem vitae provident. Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae. Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque. 1999-02-28 9 9 Similique at quia quia ut recusandae repudiandae delectus. Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem. Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis. 2007-08-07 10 10 Est vel aperiam ipsa quod doloremque et est et. Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem. Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia. 2009-07-18 11 1 Sint est qui dolorem eum accusantium repudiandae. Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa. Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum. 2010-04-16 12 2 Culpa debitis ut non sapiente voluptatem. Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus. Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit. 1988-12-26 13 3 Ut ut rerum qui quis sed sunt. Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni. Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis. 2001-06-01 14 4 Error inventore delectus sapiente non. Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores. Voluptatum id amet qui quia. Nemo nulla atque dignissimos. 1974-12-07 15 5 Ut aut quo aut ea occaecati est voluptas. Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus. Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim. 1999-09-12 16 6 Nihil ea qui sequi odit rem. Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi. Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut. 2003-07-28 17 7 Quia accusantium deserunt suscipit. Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi. Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis. 2015-05-24 18 8 Inventore et eaque temporibus qui aut exercitationem necessitatibus. Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt. Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam. 1996-02-06 19 9 Et soluta consequatur porro rem corrupti. Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et. Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur. 2018-03-31 20 10 Culpa error rerum voluptatem recusandae quae tempora. Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia. Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos. 2007-01-22 21 1 Harum laudantium fugiat debitis atque sed. Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae. Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia. 1987-06-29 22 2 Non architecto ut voluptas aut voluptas dolor ut. Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel. Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque. 1993-05-06 23 3 Dolores sed hic vitae ut qui. Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae. Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur. 1978-09-08 24 4 Deleniti distinctio eos eveniet. Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni. Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae. 2003-06-23 25 5 Ea et asperiores odio vel sunt exercitationem. Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est. Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio. 1972-09-16 26 6 Accusamus est sed aut minus. Et libero in in est consequuntur. Illum distinctio doloremque quas. Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor. 2017-03-08 27 7 Et sed reprehenderit nobis sed. Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum. Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est. 1973-08-04 28 8 Autem ullam aperiam totam assumenda quod esse. Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea. Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae. 2014-04-26 29 9 Ad dolores amet ea nisi aut enim voluptatem. Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla. Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in. 2006-09-07 30 10 Eos fuga at ex sapiente quasi. Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque. Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et. 2009-07-23 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/security/PostgreSQL/nxs-data-anonymizer.conf ================================================ security: policy: tables: skip columns: randomize exceptions: columns: - email - id defaults: columns: birthdate: value: "1999-12-31" filters: public.authors: columns: first_name: value: "{{- randAlphaNum 20 -}}" added: value: "2000-01-01 12:00:00" ================================================ FILE: doc/examples/security/PostgreSQL/output ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 uzQxHOrpTjP4LQLsBtuf randomized character data brett35@example.com 1999-12-31 2000-01-01 12:00:00 2 IGX35AiQbhUs8rnbwEu5 randomized character data aracely46@example.com 1999-12-31 2000-01-01 12:00:00 3 50zYnjx22diwRJrkdsHF randomized character data carroll.harris@example.com 1999-12-31 2000-01-01 12:00:00 4 rdj068aJyjJWWPGLMCvM randomized character data johns.janick@example.org 1999-12-31 2000-01-01 12:00:00 5 HUG1OQFX1zbnZbjvss2g randomized character data lakin.ramiro@example.net 1999-12-31 2000-01-01 12:00:00 6 BVXmaj17oPS6TVbgkxFK randomized character data judson33@example.com 1999-12-31 2000-01-01 12:00:00 7 dT0oZqmVrthd4VP8CHA1 randomized character data kaci.koch@example.net 1999-12-31 2000-01-01 12:00:00 8 qwhvRdMTcuFZu79qIIKa randomized character data jprosacco@example.net 1999-12-31 2000-01-01 12:00:00 9 hqfNNYZ1fylWuGKC2Lxy randomized character data kutch.kylie@example.com 1999-12-31 2000-01-01 12:00:00 10 TYBlmQpwP9mBz3X0sjj7 randomized character data hane.terrill@example.org 1999-12-31 2000-01-01 12:00:00 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/security/Readme.md ================================================ # Example `security` An example of using nxs-data-anonymizer in a simple configuration with filters and security block. An example of a configuration: ```yaml security: policy: # Policy for handling undeclared tables and columns. tables: skip columns: randomize exceptions: # Excludes policy processing for the specified tables and columns. tables: # These tables will not be skipped. - table2 columns: # These columns will not be randomized. - excluded_col1 - excluded_col2 defaults: # Overrides the default randomization value for a column with the specified value. If you use a function to generate a value, that value will be the same for all substitutions. columns: default_col1: # Column name to override the default value. value: "" filters: table1: columns: table1_col1: value: "" table1_col2: value: "" ``` Working examples of configurations in the `./MySQL` and `./PostgreSQL` directories. ================================================ FILE: doc/examples/variables/MySQL/input.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'Wilford','Wintheiser','brett35@example.com','1981-10-14','1988-09-10 18:37:25'),(2,'Nyasia','Doyle','aracely46@example.com','2007-07-01','1980-10-28 23:57:00'),(3,'Ken','Haag','carroll.harris@example.com','2003-04-16','1997-03-14 18:41:06'),(4,'Leonor','Mann','johns.janick@example.org','1996-05-18','2010-04-12 00:38:42'),(5,'Eloisa','Ratke','lakin.ramiro@example.net','1982-07-22','1996-03-25 09:07:39'),(6,'Nikolas','Dibbert','judson33@example.com','1970-02-22','1979-03-16 10:10:12'),(7,'Kelley','Koch','kaci.koch@example.net','2013-05-01','2020-08-02 02:01:34'),(8,'Glen','Howe','jprosacco@example.net','1971-08-03','1971-01-02 14:19:52'),(9,'Geovanni','Medhurst','kutch.kylie@example.com','2011-04-20','2004-06-10 12:33:11'),(10,'Zella','Davis','hane.terrill@example.org','1991-11-07','2007-09-19 13:48:20'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (1,1,'Pariatur est in ut provident vero eligendi.','Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum.','Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea.','1975-07-07'),(2,2,'Unde est architecto est.','Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel.','Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem.','1976-05-25'),(3,3,'Dignissimos perspiciatis nobis quisquam saepe ad aut numquam.','Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum.','Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum.','1991-12-21'),(4,4,'Voluptas sint modi magnam.','Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem.','Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam.','2002-01-23'),(5,5,'Sapiente rem eos enim ullam ipsum ut.','Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam.','Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia.','2017-11-19'),(6,6,'Error quas doloremque est sunt quae.','Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis.','Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id.','1974-03-23'),(7,7,'Quo impedit quos molestiae dolorum in soluta dolores non.','Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut.','Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis.','2004-12-08'),(8,8,'Nulla quia repellendus et autem vitae provident.','Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae.','Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque.','1999-02-28'),(9,9,'Similique at quia quia ut recusandae repudiandae delectus.','Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem.','Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis.','2007-08-07'),(10,10,'Est vel aperiam ipsa quod doloremque et est et.','Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem.','Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia.','2009-07-18'),(11,1,'Sint est qui dolorem eum accusantium repudiandae.','Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa.','Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum.','2010-04-16'),(12,2,'Culpa debitis ut non sapiente voluptatem.','Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus.','Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit.','1988-12-26'),(13,3,'Ut ut rerum qui quis sed sunt.','Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni.','Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis.','2001-06-01'),(14,4,'Error inventore delectus sapiente non.','Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores.','Voluptatum id amet qui quia. Nemo nulla atque dignissimos.','1974-12-07'),(15,5,'Ut aut quo aut ea occaecati est voluptas.','Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus.','Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim.','1999-09-12'),(16,6,'Nihil ea qui sequi odit rem.','Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi.','Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut.','2003-07-28'),(17,7,'Quia accusantium deserunt suscipit.','Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi.','Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis.','2015-05-24'),(18,8,'Inventore et eaque temporibus qui aut exercitationem necessitatibus.','Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt.','Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam.','1996-02-06'),(19,9,'Et soluta consequatur porro rem corrupti.','Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et.','Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur.','2018-03-31'),(20,10,'Culpa error rerum voluptatem recusandae quae tempora.','Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia.','Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos.','2007-01-22'),(21,1,'Harum laudantium fugiat debitis atque sed.','Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae.','Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia.','1987-06-29'),(22,2,'Non architecto ut voluptas aut voluptas dolor ut.','Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel.','Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque.','1993-05-06'),(23,3,'Dolores sed hic vitae ut qui.','Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae.','Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur.','1978-09-08'),(24,4,'Deleniti distinctio eos eveniet.','Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni.','Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae.','2003-06-23'),(25,5,'Ea et asperiores odio vel sunt exercitationem.','Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est.','Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio.','1972-09-16'),(26,6,'Accusamus est sed aut minus.','Et libero in in est consequuntur. Illum distinctio doloremque quas.','Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor.','2017-03-08'),(27,7,'Et sed reprehenderit nobis sed.','Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum.','Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est.','1973-08-04'),(28,8,'Autem ullam aperiam totam assumenda quod esse.','Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea.','Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae.','2014-04-26'),(29,9,'Ad dolores amet ea nisi aut enim voluptatem.','Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla.','Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in.','2006-09-07'),(30,10,'Eos fuga at ex sapiente quasi.','Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque.','Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et.','2009-07-23'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/variables/MySQL/nxs-data-anonymizer.conf ================================================ variables: first_name: value: "John" last_name: value: "Smith" email: value: "JohnSmith@example.com" birthdate: value: "1999-12-31" added: value: "2000-01-01 12:00:00" author_id: value: "1" title: value: "anont_title" description: value: "anon_description" content: value: "anon_content" date: value: "2001-01-01 12:00:00" filters: authors: columns: first_name: value: "{{ .Variables.first_name }}" last_name: value: "{{ .Variables.last_name }}" email: value: "{{ .Variables.email }}" birthdate: value: "{{ .Variables.birthdate }}" added: value: "{{ .Variables.added }}" posts: columns: author_id: value: "{{ .Variables.author_id }}" title: value: "{{ .Variables.title }}" description: value: "{{ .Variables.description }}" content: value: "{{ .Variables.content }}" date: value: "{{ .Variables.date }}" ================================================ FILE: doc/examples/variables/MySQL/output.sql ================================================ -- MySQL dump 10.13 Distrib 8.4.0, for Linux (x86_64) -- -- Host: localhost Database: name_db -- ------------------------------------------------------ -- Server version 8.4.0 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `authors` -- DROP TABLE IF EXISTS `authors`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `authors` ( `id` int NOT NULL AUTO_INCREMENT, `first_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `last_name` varchar(50) COLLATE utf8mb3_unicode_ci NOT NULL, `email` varchar(100) COLLATE utf8mb3_unicode_ci NOT NULL, `birthdate` date NOT NULL, `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `authors` -- LOCK TABLES `authors` WRITE; /*!40000 ALTER TABLE `authors` DISABLE KEYS */; INSERT INTO `authors` VALUES (1,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(2,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(3,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(4,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(5,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(6,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(7,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(8,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(9,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'),(10,'John','Smith','JohnSmith@example.com','1999-12-31','2000-01-01 12:00:00'); /*!40000 ALTER TABLE `authors` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `posts` -- DROP TABLE IF EXISTS `posts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `author_id` int NOT NULL, `title` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL, `description` varchar(500) COLLATE utf8mb3_unicode_ci NOT NULL, `content` text COLLATE utf8mb3_unicode_ci NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `posts` -- LOCK TABLES `posts` WRITE; /*!40000 ALTER TABLE `posts` DISABLE KEYS */; INSERT INTO `posts` VALUES (1,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(2,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(3,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(4,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(5,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(6,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(7,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(8,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(9,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(10,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(11,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(12,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(13,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(14,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(15,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(16,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(17,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(18,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(19,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(20,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(21,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(22,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(23,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(24,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(25,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(26,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(27,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(28,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(29,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'),(30,1,'anont_title','anon_description','anon_content','2001-01-01 12:00:00'); /*!40000 ALTER TABLE `posts` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-07-19 10:47:53 ================================================ FILE: doc/examples/variables/PostgreSQL/input ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 Wilford Wintheiser brett35@example.com 1981-10-14 1988-09-10 18:37:25 2 Nyasia Doyle aracely46@example.com 2007-07-01 1980-10-28 23:57:00 3 Ken Haag carroll.harris@example.com 2003-04-16 1997-03-14 18:41:06 4 Leonor Mann johns.janick@example.org 1996-05-18 2010-04-12 00:38:42 5 Eloisa Ratke lakin.ramiro@example.net 1982-07-22 1996-03-25 09:07:39 6 Nikolas Dibbert judson33@example.com 1970-02-22 1979-03-16 10:10:12 7 Kelley Koch kaci.koch@example.net 2013-05-01 2020-08-02 02:01:34 8 Glen Howe jprosacco@example.net 1971-08-03 1971-01-02 14:19:52 9 Geovanni Medhurst kutch.kylie@example.com 2011-04-20 2004-06-10 12:33:11 10 Zella Davis hane.terrill@example.org 1991-11-07 2007-09-19 13:48:20 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 1 1 Pariatur est in ut provident vero eligendi. Consequatur quae odio in animi. Quis dolorem aut corporis sed ratione animi et. Iure sunt qui eligendi laudantium harum maxime id id. Quia eos beatae temporibus eos rerum ipsum. Velit voluptatibus quo est dolorem quos sed et. Illum similique atque et qui. Perspiciatis magnam saepe quis. Consequatur aut dolorem ea. 1975-07-07 2 2 Unde est architecto est. Consectetur quidem aut eligendi quas. Voluptas aut voluptas ratione reiciendis magnam sint. Ratione et omnis assumenda deserunt voluptatem perspiciatis. Non voluptates quia distinctio nam consectetur vel. Sed sint at consectetur. Fugiat fugiat omnis debitis dolore. Incidunt vero incidunt enim reiciendis. Odio et illo facilis quo sit quia consequatur voluptatem. 1976-05-25 3 3 Dignissimos perspiciatis nobis quisquam saepe ad aut numquam. Voluptatibus eum voluptas eveniet veniam ducimus. Modi id vitae est accusamus. Quaerat perferendis voluptas minima dignissimos et. Sapiente explicabo voluptas commodi voluptatem autem totam. Adipisci quos quos quo ea aliquid rerum. Repellat minus enim occaecati sunt quas. Ab ipsa voluptatibus sunt eos omnis quisquam at voluptatibus. Quo vitae doloremque nesciunt doloremque. Temporibus rerum sunt iste dolores rerum. 1991-12-21 4 4 Voluptas sint modi magnam. Facere harum pariatur quo eveniet dolor molestias. Quo debitis corporis quasi minima et optio. Ut maiores nihil rerum autem culpa et voluptates. Amet totam rem optio in. Provident ea repudiandae quisquam unde occaecati autem. Sed quia assumenda quis rerum praesentium harum. Quia minima quo natus. Impedit temporibus perspiciatis et enim doloremque nihil et. Perspiciatis nam occaecati illo dicta asperiores eos nam. 2002-01-23 5 5 Sapiente rem eos enim ullam ipsum ut. Officia quos voluptas autem consequuntur. Quis consequatur aut vel dolor. Sapiente voluptatem quibusdam dolor nobis earum laboriosam quisquam. Quibusdam vel tempora explicabo qui. Sunt animi a unde veritatis perferendis similique nostrum vel. Porro ab ad cumque dolorum provident distinctio est ipsum. Esse maxime ea quia. 2017-11-19 6 6 Error quas doloremque est sunt quae. Corporis quis in sint. Eos vitae aut provident distinctio ullam. Corporis mollitia quam natus qui sapiente officiis. Ipsam animi aperiam ipsa fuga. Sunt blanditiis possimus aut quod. Doloremque possimus occaecati numquam omnis dolor. Qui nihil qui atque vitae sapiente illo id. 1974-03-23 7 7 Quo impedit quos molestiae dolorum in soluta dolores non. Harum quasi dolorum et harum iste eveniet et. Cumque ab recusandae architecto est ipsam est. Eligendi et earum ea alias odio sed ut. Illo earum porro corporis sunt aut. Vel quisquam ut voluptas reiciendis maiores cumque. Qui hic maiores voluptas sapiente reprehenderit. Eos non autem quis maiores perferendis. 2004-12-08 8 8 Nulla quia repellendus et autem vitae provident. Facere deserunt suscipit quia et et totam vel at. Cumque suscipit est ea quis in quos. Harum dolorum consequuntur illum voluptatem iste enim recusandae. Excepturi hic tenetur sint nostrum. Nihil itaque repudiandae qui hic minima quis ut. Dolor et aut quaerat exercitationem minima ut. Blanditiis minus et qui dolor ut atque. 1999-02-28 9 9 Similique at quia quia ut recusandae repudiandae delectus. Et necessitatibus aut accusantium quisquam harum est. Non quam id impedit deleniti. Eaque non architecto facere dolorem nesciunt perferendis. Delectus nihil ut dignissimos. Voluptate rerum reprehenderit aut voluptatem quibusdam quidem. Tempore iusto minus omnis tempore. Hic aut sequi temporibus consequatur. In vel enim eos nihil sed eos debitis. 2007-08-07 10 10 Est vel aperiam ipsa quod doloremque et est et. Facere ut et similique voluptates voluptas blanditiis explicabo. Eaque molestiae nihil sed et repellat voluptatem eum autem. Rem laudantium in aut assumenda. Aspernatur id illo pariatur aut deleniti rem et. Nisi velit neque qui quia. 2009-07-18 11 1 Sint est qui dolorem eum accusantium repudiandae. Quia tenetur culpa maiores molestias. Id numquam illum earum quos sint ad dolore corrupti. Consequatur quasi itaque est odit qui quod culpa. Omnis tenetur occaecati accusamus quis corrupti et ipsam. Ullam nobis tempore officia nesciunt iste. Nesciunt vel in eos. Dolor voluptates quod sed quibusdam ut. Fuga quia eum quidem cum. 2010-04-16 12 2 Culpa debitis ut non sapiente voluptatem. Commodi fugit ullam quaerat quam quo minus. Harum quam ipsam ducimus sit expedita sit. Eos natus quo quibusdam quam repudiandae. Assumenda et sint sit quia qui necessitatibus. Eum molestiae cupiditate ut minus. Eaque eos eos ipsam voluptatem. Sint aut aliquid modi id dolores consequatur. Aut nemo blanditiis nisi ea nam velit. 1988-12-26 13 3 Ut ut rerum qui quis sed sunt. Tenetur enim et nisi ex et consequatur omnis nisi. Eos deleniti aut amet illo sed quibusdam. Consequuntur sint quia quia aut magni. Aut eveniet natus ut. Nostrum aliquid qui nam hic iusto id occaecati qui. Est dolor accusamus qui saepe voluptatem dolorem omnis. 2001-06-01 14 4 Error inventore delectus sapiente non. Aliquam ut aliquid et laboriosam distinctio ab. Tempore molestiae aut ea nesciunt culpa. Eum maiores molestiae voluptatem animi aliquam. Aspernatur aut soluta totam occaecati in nam ratione asperiores. Voluptatum id amet qui quia. Nemo nulla atque dignissimos. 1974-12-07 15 5 Ut aut quo aut ea occaecati est voluptas. Non deleniti molestias velit ut eos veritatis. Et id eaque numquam ipsa iure ut. Molestiae et minus natus. Necessitatibus asperiores adipisci eaque. Alias sunt illum fugit ab labore laborum est odio. Aspernatur esse qui ut omnis autem. Laudantium quos corporis numquam sapiente enim. 1999-09-12 16 6 Nihil ea qui sequi odit rem. Omnis ea accusantium qui commodi et ducimus. Magni deserunt sed quo velit. Hic cum tenetur facilis. Non eum quis molestias sunt. Illo saepe architecto doloremque illum sequi. Nihil iste illum vitae ipsa et et. Reiciendis sint illum quo dignissimos veritatis. Velit eum architecto enim ratione aut. 2003-07-28 17 7 Quia accusantium deserunt suscipit. Repellat et molestiae magnam quaerat et iure. Enim enim cum quisquam quasi. Maiores officiis beatae hic hic dolor non officiis. Nulla beatae at aut fugit doloribus et provident. Debitis non dolores iusto impedit. Alias blanditiis velit voluptate et debitis. 2015-05-24 18 8 Inventore et eaque temporibus qui aut exercitationem necessitatibus. Omnis molestias nemo culpa est dicta dolorem porro. Illum est ut ut molestias similique sit sunt. Consequatur asperiores quaerat voluptate incidunt. Unde quibusdam asperiores voluptates quaerat et aliquam. Libero at est quibusdam eos aut. Aut voluptatem tempora a nam. 1996-02-06 19 9 Et soluta consequatur porro rem corrupti. Ullam doloremque explicabo ea ab quam ipsum. Et qui iure vero tempore voluptate aut. Ullam id ab accusamus optio voluptas. Quia quaerat quibusdam aut accusantium impedit et. Perspiciatis sed dolores aut. Animi sed totam exercitationem fugiat dolores. Ipsa dolorem quia non aliquam. Rerum exercitationem voluptatem dolor beatae veritatis quasi omnis consectetur. 2018-03-31 20 10 Culpa error rerum voluptatem recusandae quae tempora. Est ullam tempore autem et. Dolorum est eius eaque veniam in quibusdam neque. Ut aspernatur earum sint delectus voluptate deserunt sapiente quia. Enim quos facere rerum ipsa. Eveniet expedita id eligendi voluptatem magnam quo eos. 2007-01-22 21 1 Harum laudantium fugiat debitis atque sed. Et asperiores magni qui voluptas a consequatur totam. Inventore enim quaerat consequatur sint quam voluptatibus optio. Est aut repellendus repudiandae reiciendis eveniet veniam. Minima a corrupti non quae. Voluptate officia ut debitis explicabo corrupti facere reprehenderit. Enim id recusandae vitae est dolores. Aperiam consequuntur ex beatae et alias quia. 1987-06-29 22 2 Non architecto ut voluptas aut voluptas dolor ut. Dolore delectus optio fuga aut labore necessitatibus. Laborum quis nulla deserunt. Aut corporis repellendus inventore vel. Facilis soluta ab culpa est. Aut pariatur et dicta sit. Sed qui est numquam est.\nAtque ex sit eveniet. Iure accusamus optio placeat voluptate non sit ea. Sint dignissimos dolorum debitis ipsam neque. 1993-05-06 23 3 Dolores sed hic vitae ut qui. Libero illum dolorum est eaque ut. Nesciunt qui vitae recusandae eveniet saepe et ut. Aliquid enim vitae beatae animi quam doloribus accusamus. Eos eos excepturi accusamus ut recusandae. Distinctio molestiae sint qui. Expedita qui ex dignissimos architecto quo sapiente alias eveniet. Laborum qui aut est doloribus a beatae. Unde adipisci consequuntur et tenetur. 1978-09-08 24 4 Deleniti distinctio eos eveniet. Ex aperiam animi quis excepturi. Velit qui molestias iste iure voluptatem. Eveniet adipisci quasi amet. Soluta laborum aperiam magni. Deserunt dolores ut ut ex cum. Quae iusto rerum voluptatum aperiam. Vel voluptatem ut nesciunt delectus blanditiis. Sequi consequuntur temporibus sunt dolores repudiandae. 2003-06-23 25 5 Ea et asperiores odio vel sunt exercitationem. Quod necessitatibus quis sit aspernatur a. Molestias laudantium voluptatibus quaerat rerum cupiditate. Aut consectetur quia doloribus repellat porro est. Et alias soluta aliquam qui aut. Explicabo quo consequuntur consequuntur velit distinctio. 1972-09-16 26 6 Accusamus est sed aut minus. Et libero in in est consequuntur. Illum distinctio doloremque quas. Neque vel tenetur libero sed aut voluptas. Itaque quod et laudantium magnam tempora qui non. Et sapiente dolores reiciendis sit ab fugiat sed sequi. Reiciendis maxime qui aut laborum dolor. 2017-03-08 27 7 Et sed reprehenderit nobis sed. Totam amet nisi id quod. Laudantium maxime rem velit consequuntur amet. Et enim eum aspernatur totam. Nulla consequatur similique maxime et qui rerum. Iure sequi unde consectetur neque in magni. Illo ipsa commodi quae placeat modi numquam numquam. Quae culpa sit distinctio vitae est. 1973-08-04 28 8 Autem ullam aperiam totam assumenda quod esse. Aut incidunt aspernatur aut sapiente ipsum repellat. Molestiae eaque accusantium maxime. Velit modi ea consectetur natus ea. Molestias voluptatum cupiditate et minus qui consequuntur. Reprehenderit aut at corrupti. Eius unde ullam aut cum eius molestiae. 2014-04-26 29 9 Ad dolores amet ea nisi aut enim voluptatem. Eum voluptates sunt occaecati molestiae. Cupiditate labore expedita eius in omnis non. Sit cumque unde cupiditate sequi eius reprehenderit nulla. Voluptates modi esse quas sit eos praesentium. Quas et rem vero quo veritatis voluptas. Inventore dolorem ut praesentium consequatur rem. Amet ipsam quia officia iste est in. 2006-09-07 30 10 Eos fuga at ex sapiente quasi. Facere dolores non omnis facilis. Nam cupiditate maiores iure quia adipisci numquam magnam. Esse voluptas voluptatem cum ea voluptas doloremque. Voluptatem qui qui magnam quis eos. Consequatur ut repudiandae libero dignissimos et quia velit. Eum nisi facere consequatur quod ut. Ad molestiae voluptatem eaque iste et. 2009-07-23 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/variables/PostgreSQL/nxs-data-anonymizer.conf ================================================ variables: first_name: value: "John" last_name: value: "Smith" email: value: "JohnSmith@example.com" birthdate: value: "1999-12-31" added: value: "2000-01-01 12:00:00" author_id: value: "1" title: value: "anont_title" description: value: "anon_description" content: value: "anon_content" date: value: "2001-01-01 12:00:00" filters: public.authors: columns: first_name: value: "{{ .Variables.first_name }}" last_name: value: "{{ .Variables.last_name }}" email: value: "{{ .Variables.email }}" birthdate: value: "{{ .Variables.birthdate }}" added: value: "{{ .Variables.added }}" public.posts: columns: author_id: value: "{{ .Variables.author_id }}" title: value: "{{ .Variables.title }}" description: value: "{{ .Variables.description }}" content: value: "{{ .Variables.content }}" date: value: "{{ .Variables.date }}" ================================================ FILE: doc/examples/variables/PostgreSQL/output ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: authors; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.authors ( id integer NOT NULL, first_name character varying(50) NOT NULL, last_name character varying(50) NOT NULL, email character varying(100) NOT NULL, birthdate date NOT NULL, added timestamp without time zone NOT NULL ); ALTER TABLE public.authors OWNER TO postgres; -- -- Name: posts; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.posts ( id integer NOT NULL, author_id integer NOT NULL, title character varying(255) NOT NULL, description character varying(500) NOT NULL, content text NOT NULL, date date NOT NULL ); ALTER TABLE public.posts OWNER TO postgres; -- -- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.authors (id, first_name, last_name, email, birthdate, added) FROM stdin; 1 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 2 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 3 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 4 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 5 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 6 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 7 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 8 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 9 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 10 John Smith JohnSmith@example.com 1999-12-31 2000-01-01 12:00:00 \. -- -- Data for Name: posts; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.posts (id, author_id, title, description, content, date) FROM stdin; 1 1 anont_title anon_description anon_content 2001-01-01 12:00:00 2 1 anont_title anon_description anon_content 2001-01-01 12:00:00 3 1 anont_title anon_description anon_content 2001-01-01 12:00:00 4 1 anont_title anon_description anon_content 2001-01-01 12:00:00 5 1 anont_title anon_description anon_content 2001-01-01 12:00:00 6 1 anont_title anon_description anon_content 2001-01-01 12:00:00 7 1 anont_title anon_description anon_content 2001-01-01 12:00:00 8 1 anont_title anon_description anon_content 2001-01-01 12:00:00 9 1 anont_title anon_description anon_content 2001-01-01 12:00:00 10 1 anont_title anon_description anon_content 2001-01-01 12:00:00 11 1 anont_title anon_description anon_content 2001-01-01 12:00:00 12 1 anont_title anon_description anon_content 2001-01-01 12:00:00 13 1 anont_title anon_description anon_content 2001-01-01 12:00:00 14 1 anont_title anon_description anon_content 2001-01-01 12:00:00 15 1 anont_title anon_description anon_content 2001-01-01 12:00:00 16 1 anont_title anon_description anon_content 2001-01-01 12:00:00 17 1 anont_title anon_description anon_content 2001-01-01 12:00:00 18 1 anont_title anon_description anon_content 2001-01-01 12:00:00 19 1 anont_title anon_description anon_content 2001-01-01 12:00:00 20 1 anont_title anon_description anon_content 2001-01-01 12:00:00 21 1 anont_title anon_description anon_content 2001-01-01 12:00:00 22 1 anont_title anon_description anon_content 2001-01-01 12:00:00 23 1 anont_title anon_description anon_content 2001-01-01 12:00:00 24 1 anont_title anon_description anon_content 2001-01-01 12:00:00 25 1 anont_title anon_description anon_content 2001-01-01 12:00:00 26 1 anont_title anon_description anon_content 2001-01-01 12:00:00 27 1 anont_title anon_description anon_content 2001-01-01 12:00:00 28 1 anont_title anon_description anon_content 2001-01-01 12:00:00 29 1 anont_title anon_description anon_content 2001-01-01 12:00:00 30 1 anont_title anon_description anon_content 2001-01-01 12:00:00 \. -- -- Name: authors authors_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.authors ADD CONSTRAINT authors_pkey PRIMARY KEY (id); -- -- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.posts ADD CONSTRAINT posts_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: doc/examples/variables/Readme.md ================================================ # Example `variables` An example of using nxs-data-anonymizer in a simple configuration with filters and variables blocks. In order to use variables in the "filters" block, you need to describe the "variables" block: ```yaml variables: some_variable: # Variable name value: "some_value" # Variable value ``` If you use a function to generate a value, then in this block it will be executed once and the resulting value will be the same for all its occurrences in the dump. An example of a configuration: ```yaml variables: var1: value: "" var2: value: "" var3: value: "" filters: table1: columns: table1_col1: value: "" table1_col2: value: "{{ .Variables.var1 }}" table1_col3: value: "{{ .Variables.var2 }}" table2: columns: table2_col1: value: "" table2_col2: value: "{{ .Variables.var1 }}" table2_col3: value: "{{ .Variables.var3 }}" ``` Working examples of configurations in the `./MySQL` and `./PostgreSQL` directories. ================================================ FILE: ds/mysql/mysql.go ================================================ package mysql import ( "fmt" gmysql "gorm.io/driver/mysql" "gorm.io/gorm" ) type MySQL struct { client *gorm.DB } type Settings struct { Host string Port int User string Password string Database string } func Connect(s Settings) (MySQL, error) { client, err := gorm.Open(gmysql.Open(fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", s.User, s.Password, s.Host, s.Port, s.Database)), &gorm.Config{}) if err != nil { return MySQL{}, err } return MySQL{ client: client, }, nil } func (m *MySQL) Close() error { db, _ := m.client.DB() return db.Close() } func (m *MySQL) DBCleanup() error { tables, err := m.client.Migrator().GetTables() if err != nil { return fmt.Errorf("drop tables, get tables: %w", err) } for _, t := range tables { if err := m.client.Migrator().DropTable(t); err != nil { return fmt.Errorf("drop tables, table `%s`: %w", t, err) } } return nil } ================================================ FILE: go.mod ================================================ module github.com/nixys/nxs-data-anonymizer go 1.21.1 require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/docker/go-units v0.5.0 github.com/go-sql-driver/mysql v1.7.1 github.com/nixys/nxs-go-appctx/v3 v3.0.0 github.com/nixys/nxs-go-conf v1.1.0 github.com/nixys/nxs-go-fsm v1.0.0 github.com/pborman/getopt/v2 v2.1.0 github.com/sirupsen/logrus v1.9.3 gorm.io/driver/mysql v1.5.1 gorm.io/gorm v1.25.2 ) require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/google/uuid v1.3.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.1.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/stretchr/testify v1.8.0 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/sys v0.10.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) ================================================ FILE: go.sum ================================================ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= 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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/nixys/nxs-go-appctx/v3 v3.0.0 h1:Uib9UpNVrAy2AArPfNo3LwV+269Sj1PrZqAYuZt+KGY= github.com/nixys/nxs-go-appctx/v3 v3.0.0/go.mod h1:+1l3Gjr1FW/rhmYXi7GaftFu0N6H6o8L13/fQUzhPIE= github.com/nixys/nxs-go-conf v1.1.0 h1:FGm9D/1gpFcfRIdvfrsup9if5PvyQxc/VhE/85+n5BQ= github.com/nixys/nxs-go-conf v1.1.0/go.mod h1:m2zxhmA7YfWdFdmTQZSqP0+C16oRUztfXss+yhbScgY= github.com/nixys/nxs-go-fsm v1.0.0 h1:BGxlFdzMSaqkaW3Q3Iikl1VkeyZ3L7idnQWbGMDOWW0= github.com/nixys/nxs-go-fsm v1.0.0/go.mod h1:di5WCie2YX6tL2262v/sq67lj49MVovw+A1WM++f4gI= github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmOEA= github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho= gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= ================================================ FILE: interfaces/anonymizer.go ================================================ package interfaces import ( "context" "io" ) type Anonymizer interface { Run(context.Context, io.Writer) error } ================================================ FILE: main.go ================================================ package main import ( "context" "os" "syscall" "github.com/nixys/nxs-data-anonymizer/ctx" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/routines/anonymizer" _ "github.com/go-sql-driver/mysql" appctx "github.com/nixys/nxs-go-appctx/v3" ) func main() { err := appctx.Init(context.Background()). RoutinesSet( map[string]appctx.RoutineParam{ "anonymizer": { Handler: anonymizer.Runtime, }, }, ). ValueInitHandlerSet(ctx.AppCtxInit). SignalsSet([]appctx.SignalsParam{ { Signals: []os.Signal{ syscall.SIGTERM, }, Handler: sigHandlerTerm, }, }). Run() if err != nil { switch err { case misc.ErrArgSuccessExit: os.Exit(0) default: os.Exit(1) } } } func sigHandlerTerm(sig appctx.Signal) { sig.Shutdown(nil) } ================================================ FILE: misc/errors.go ================================================ package misc import "errors" var ( ErrNotFound = errors.New("entity not found") ErrIDEmpty = errors.New("empty id") ErrUsernameEmpty = errors.New("empty username") ErrConig = errors.New("incorrect config") ErrArgSuccessExit = errors.New("arg success exit") ErrRuntime = errors.New("runtime error") ) ================================================ FILE: misc/security.go ================================================ package misc type SecurityPolicyTablesType string const ( SecurityPolicyTablesUnknown SecurityPolicyTablesType = "unknown" SecurityPolicyTablesPass SecurityPolicyTablesType = "pass" SecurityPolicyTablesSkip SecurityPolicyTablesType = "skip" ) func (v SecurityPolicyTablesType) String() string { return string(v) } func SecurityPolicyTablesTypeFromString(v string) SecurityPolicyTablesType { switch v { case string(SecurityPolicyTablesPass): return SecurityPolicyTablesPass case string(SecurityPolicyTablesSkip): return SecurityPolicyTablesSkip default: return SecurityPolicyTablesUnknown } } type SecurityPolicyColumnsType string const ( SecurityPolicyColumnsUnknown SecurityPolicyColumnsType = "unknown" SecurityPolicyColumnsPass SecurityPolicyColumnsType = "pass" SecurityPolicyColumnsRandomize SecurityPolicyColumnsType = "randomize" ) func (v SecurityPolicyColumnsType) String() string { return string(v) } func SecurityPolicyColumnsTypeFromString(v string) SecurityPolicyColumnsType { switch v { case string(SecurityPolicyColumnsPass): return SecurityPolicyColumnsPass case string(SecurityPolicyColumnsRandomize): return SecurityPolicyColumnsRandomize default: return SecurityPolicyColumnsUnknown } } ================================================ FILE: misc/template.go ================================================ package misc import ( "bytes" ttemplate "text/template" "github.com/Masterminds/sprig/v3" ) var ( TemplateNULL = "::NULL::" TemplateDrop = "::DROP::" ) type TemlateRes struct { Value string DropRow bool } // TemplateExec makes message from given template `tpl` and data `d` func TemplateExec(tpl string, d any) (TemlateRes, error) { var b bytes.Buffer // See http://masterminds.github.io/sprig/ for details t, err := ttemplate.New("template").Funcs(func() ttemplate.FuncMap { // Get current sprig functions t := sprig.TxtFuncMap() // Add additional functions t["null"] = func() string { return TemplateNULL } t["isNull"] = func(v string) bool { if v == TemplateNULL { return true } return false } t["drop"] = func() string { return TemplateDrop } return t }()).Parse(tpl) if err != nil { return TemlateRes{}, err } err = t.Execute(&b, d) if err != nil { return TemlateRes{}, err } // Return empty line if buffer is nil if b.Bytes() == nil { return TemlateRes{ Value: "", DropRow: false, }, nil } // Return `drop` value if buffer is DROP (with special key) if bytes.Equal(b.Bytes(), []byte(TemplateDrop)) { return TemlateRes{ Value: "", DropRow: true, }, nil } // Return buffer content otherwise return TemlateRes{ Value: b.String(), DropRow: false, }, nil } ================================================ FILE: misc/token.go ================================================ package misc import ( "math/rand" "time" ) // TokenGen generates token string func TokenGen(tokenLen int64) string { var chars = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") rand.Seed(time.Now().UnixNano()) b := make([]rune, tokenLen) for i := range b { b[i] = chars[rand.Intn(len(chars))] } return string(b) } ================================================ FILE: misc/values.go ================================================ package misc type ValueType string const ( ValueTypeUnknown ValueType = "unkonwn" ValueTypeTemplate ValueType = "template" ValueTypeCommand ValueType = "command" ) func ValueTypeFromString(v string) ValueType { switch v { case string(ValueTypeTemplate): return ValueTypeTemplate case string(ValueTypeCommand): return ValueTypeCommand default: return ValueTypeUnknown } } func (v ValueType) String() string { return string(v) } ================================================ FILE: modules/anonymizers/mysql/.testdata/mysql_test.dos.in.sql ================================================ -- MariaDB dump 10.19 Distrib 10.6.12-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: 127.0.0.1 Database: db -- ------------------------------------------------------ -- Server version 8.0.32 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `table1` -- DROP TABLE IF EXISTS `table1`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table1` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table1` -- LOCK TABLES `table1` WRITE; /*!40000 ALTER TABLE `table1` DISABLE KEYS */; INSERT INTO `table1` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table1` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table2` -- DROP TABLE IF EXISTS `table2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table2` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table2` -- LOCK TABLES `table2` WRITE; /*!40000 ALTER TABLE `table2` DISABLE KEYS */; INSERT INTO `table2` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table2` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table3` -- DROP TABLE IF EXISTS `table3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table3` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table3` -- LOCK TABLES `table3` WRITE; /*!40000 ALTER TABLE `table3` DISABLE KEYS */; INSERT INTO `table3` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table3` ENABLE KEYS */; UNLOCK TABLES; ================================================ FILE: modules/anonymizers/mysql/.testdata/mysql_test.dos.out.sql ================================================ -- MariaDB dump 10.19 Distrib 10.6.12-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: 127.0.0.1 Database: db -- ------------------------------------------------------ -- Server version 8.0.32 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `table1` -- DROP TABLE IF EXISTS `table1`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table1` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table1` -- LOCK TABLES `table1` WRITE; /*!40000 ALTER TABLE `table1` DISABLE KEYS */; INSERT INTO `table1` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table1` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table2` -- DROP TABLE IF EXISTS `table2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table2` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table2` -- LOCK TABLES `table2` WRITE; /*!40000 ALTER TABLE `table2` DISABLE KEYS */; /*!40000 ALTER TABLE `table2` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table3` -- DROP TABLE IF EXISTS `table3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table3` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table3` -- LOCK TABLES `table3` WRITE; /*!40000 ALTER TABLE `table3` DISABLE KEYS */; INSERT INTO `table3` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table3` ENABLE KEYS */; UNLOCK TABLES; ================================================ FILE: modules/anonymizers/mysql/.testdata/mysql_test.in.sql ================================================ -- MariaDB dump 10.19 Distrib 10.6.12-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: 127.0.0.1 Database: db -- ------------------------------------------------------ -- Server version 8.0.32 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `table1` -- DROP TABLE IF EXISTS `table1`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table1` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table1` -- LOCK TABLES `table1` WRITE; /*!40000 ALTER TABLE `table1` DISABLE KEYS */; INSERT INTO `table1` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table1` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table2` -- DROP TABLE IF EXISTS `table2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table2` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table2` -- LOCK TABLES `table2` WRITE; /*!40000 ALTER TABLE `table2` DISABLE KEYS */; INSERT INTO `table2` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table2` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table3` -- DROP TABLE IF EXISTS `table3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table3` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table3` -- LOCK TABLES `table3` WRITE; /*!40000 ALTER TABLE `table3` DISABLE KEYS */; INSERT INTO `table3` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table3` ENABLE KEYS */; UNLOCK TABLES; ================================================ FILE: modules/anonymizers/mysql/.testdata/mysql_test.out.sql ================================================ -- MariaDB dump 10.19 Distrib 10.6.12-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: 127.0.0.1 Database: db -- ------------------------------------------------------ -- Server version 8.0.32 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `table1` -- DROP TABLE IF EXISTS `table1`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table1` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table1` -- LOCK TABLES `table1` WRITE; /*!40000 ALTER TABLE `table1` DISABLE KEYS */; INSERT INTO `table1` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table1` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table2` -- DROP TABLE IF EXISTS `table2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table2` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table2` -- LOCK TABLES `table2` WRITE; /*!40000 ALTER TABLE `table2` DISABLE KEYS */; /*!40000 ALTER TABLE `table2` ENABLE KEYS */; UNLOCK TABLES; -- -- Table structure for table `table3` -- DROP TABLE IF EXISTS `table3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `table3` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `url` varchar(255) NOT NULL, `auth_method` varchar(20) NOT NULL DEFAULT 'none', `auth_data` text NOT NULL, `username` varchar(20) NOT NULL DEFAULT '', `password` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `table3` -- LOCK TABLES `table3` WRITE; /*!40000 ALTER TABLE `table3` DISABLE KEYS */; INSERT INTO `table3` VALUES (1,'test4','https://github.com/nixys/nxs-rbac-operator0.git','none','','',''),(2,'test5','https://github.com/nixys/nxs-rbac-operator.git','none','','',''),(3,'test6','https://github.com/nixys/nxs-rbac-operator2.git','none','','',''); /*!40000 ALTER TABLE `table3` ENABLE KEYS */; UNLOCK TABLES; ================================================ FILE: modules/anonymizers/mysql/dh.go ================================================ package mysql_anonymize import ( "bytes" "fmt" "regexp" "github.com/nixys/nxs-data-anonymizer/misc" ) func dhSecurityInsertInto(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) uctx.security.tmpBuf = token uctx.insertIntoBuf = nil return deferred, nil } func dhSecurityInsertIntoTableNameSearch(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) uctx.security.tmpBuf = append(uctx.security.tmpBuf, deferred...) uctx.security.tmpBuf = append(uctx.security.tmpBuf, token...) return []byte{}, nil } func dhSecurityInsertIntoValues(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } uctx.insertIntoBuf = append(uctx.insertIntoBuf, deferred...) uctx.insertIntoBuf = append(uctx.insertIntoBuf, token...) return []byte{}, nil } func dhSecurityInsertIntoValueSearch(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } uctx.insertIntoBuf = append(uctx.insertIntoBuf, deferred...) return []byte{}, nil } func dhSecurityValuesEnd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } if uctx.insertIntoBuf != nil { return []byte{}, nil } return append(deferred, token...), nil } func dhCreateTableName(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) uctx.filter.TableCreate(string(deferred)) return append(deferred, token...), nil } func dhCreateTableFieldName(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) uctx.columnName = string(deferred) return append(deferred, token...), nil } // checkGenerated returns true when specified type is `generated` // See: https://dev.mysql.com/blog-archive/generated-columns-in-mysql-5-7-5 for details func checkGenerated(t []byte) bool { if bytes.Contains(t, []byte{'A', 'S'}) == true { b, _ := regexp.Match("^([A-Z]+)((\\([0-9]+\\) )| )(GENERATED ALWAYS AS|AS)", t) return b } return false } func dhCreateTableColumnAdd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) traw := bytes.TrimSpace(deferred) trawUpper := bytes.ToUpper(traw) if checkGenerated(trawUpper) == false { t, b := uctx.tables[uctx.filter.TableNameGet()] if !b { t = make(map[string]columnType) } t[uctx.columnName] = columnTypeNone for _, ot := range uctx.optKinds { if ot.r.Match(trawUpper) == true { t[uctx.columnName] = ot.t break } } uctx.tables[uctx.filter.TableNameGet()] = t uctx.filter.ColumnAdd(uctx.columnName, string(traw)) } uctx.columnName = "" return append(deferred, token...), nil } func dhInsertIntoTableName(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) tn := string(deferred) // Check table pass through security rules if !securityPolicyCheck(uctx, tn) { // If not: table will be skipped from result dump uctx.security.isSkip = true uctx.security.tmpBuf = []byte{} return []byte{}, nil } uctx.insertIntoBuf = append(uctx.security.tmpBuf, append(deferred, token...)...) uctx.security.isSkip = false uctx.security.tmpBuf = []byte{} // Check insert into table name if tn != uctx.filter.TableNameGet() { return []byte{}, fmt.Errorf("`create` and `insert into` table names are mismatch (create table: '%s', insert into table: '%s')", uctx.filter.TableNameGet(), tn) } return []byte{}, nil } func dhCreateTableValues(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } s := string(deferred) if s == "NULL" { uctx.filter.ValueAdd(misc.TemplateNULL) } else { uctx.filter.ValueAdd(s) } return []byte{}, nil } func dhCreateTableValuesString(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } s := string(deferred) uctx.filter.ValueAdd(s) return []byte{}, nil } func dhCreateTableValuesEnd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } s := string(deferred) if s == "NULL" { uctx.filter.ValueAdd(misc.TemplateNULL) } else { uctx.filter.ValueAdd(s) } // Apply filter for row if err := uctx.filter.Apply(); err != nil { return []byte{}, err } b := rowDataGen(uctx) if b == nil { return []byte{}, nil } else { if uctx.insertIntoBuf != nil { b = append(uctx.insertIntoBuf, b...) uctx.insertIntoBuf = nil } else { b = append([]byte{','}, b...) } } return b, nil } func dhCreateTableValuesStringEnd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } // Apply filter for row if err := uctx.filter.Apply(); err != nil { return []byte{}, err } b := rowDataGen(uctx) if b == nil { return []byte{}, nil } else { if uctx.insertIntoBuf != nil { b = append(uctx.insertIntoBuf, b...) uctx.insertIntoBuf = nil } else { b = append([]byte{','}, b...) } } return b, nil } func rowDataGen(uctx *userCtx) []byte { var out string row := uctx.filter.ValuePop() if row.Values == nil { return nil } for i, v := range row.Values { if i > 0 { out += "," } if v.V == misc.TemplateNULL { out += "NULL" } else { switch uctx.tables[uctx.filter.TableNameGet()][uctx.filter.ColumnGetName(i)] { case columnTypeString: out += fmt.Sprintf("'%s'", v.V) case columnTypeBinary: out += fmt.Sprintf("_binary '%s'", v.V) default: out += fmt.Sprintf("%s", v.V) } } } return []byte(fmt.Sprintf("(%s)", out)) } // SecurityPolicyCheck checks the table passes the security rules // true: pass // false: skip func securityPolicyCheck(uctx *userCtx, tname string) bool { // Continue if security policy is `skip` if uctx.security.tablesPolicy != misc.SecurityPolicyTablesSkip { return true } // Check rules for specified table name if tr := uctx.filter.TableRulesLookup(tname); tr != nil { return true } // Check specified table name in exceptions if _, b := uctx.security.tableExceptions[tname]; b == true { return true } return false } ================================================ FILE: modules/anonymizers/mysql/mysql.go ================================================ package mysql_anonymize import ( "context" "fmt" "io" "regexp" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" fsm "github.com/nixys/nxs-go-fsm" ) type MySQL struct { uctx *userCtx sourceReader io.Reader } type InitOpts struct { Variables map[string]relfilter.VariableRuleOpts Security SecurityOpts Rules RulesOpts Link []relfilter.LinkOpts } type RulesOpts struct { TableRules map[string]map[string]relfilter.ColumnRuleOpts DefaultRules map[string]relfilter.ColumnRuleOpts ExceptionColumns []string TypeRuleCustom []relfilter.TypeRuleOpts } type SecurityOpts struct { TablesPolicy misc.SecurityPolicyTablesType ColumnsPolicy misc.SecurityPolicyColumnsType TableExceptions []string } type userCtx struct { filter *relfilter.Filter columnName string security securityCtx tables map[string]map[string]columnType optKinds []optKind insertIntoBuf []byte } type securityCtx struct { tmpBuf []byte isSkip bool tablesPolicy misc.SecurityPolicyTablesType tableExceptions map[string]any } type optKind struct { r *regexp.Regexp t columnType } type columnType string const ( columnTypeNone columnType = "none" columnTypeString columnType = "string" columnTypeNum columnType = "numeric" columnTypeBinary columnType = "binary" ) func (c columnType) String() string { return string(c) } var typeKeys = map[string]columnType{ // Strings "^CHAR": columnTypeString, "^VARCHAR": columnTypeString, "^TINYTEXT": columnTypeString, "^TEXT": columnTypeString, "^MEDIUMTEXT": columnTypeString, "^LONGTEXT": columnTypeString, "^ENUM": columnTypeString, "^SET": columnTypeString, "^DATE": columnTypeString, "^DATETIME": columnTypeString, "^TIME": columnTypeString, "^YEAR": columnTypeString, "^JSON": columnTypeString, // Numeric "^BIT": columnTypeNum, "^BOOL": columnTypeNum, "^TINYINT": columnTypeNum, "^SMALLINT": columnTypeNum, "^MEDIUMINT": columnTypeNum, "^INT": columnTypeNum, "^BIGINT": columnTypeNum, "^FLOAT": columnTypeNum, "^DOUBLE": columnTypeNum, "^DEC": columnTypeNum, // Binary "^BINARY": columnTypeBinary, "^VARBINARY": columnTypeBinary, "^TINYBLOB": columnTypeBinary, "^BLOB": columnTypeBinary, "^MEDIUMBLOB": columnTypeBinary, "^LONGBLOB": columnTypeBinary, } func userCtxInit(s InitOpts) (*userCtx, error) { f, err := relfilter.Init( relfilter.InitOpts{ Variables: s.Variables, Link: s.Link, TableRules: s.Rules.TableRules, DefaultRules: s.Rules.DefaultRules, ExceptionColumns: s.Rules.ExceptionColumns, TypeRuleCustom: s.Rules.TypeRuleCustom, TypeRuleDefault: typeRuleDefault, ColumnsPolicy: s.Security.ColumnsPolicy, }, ) if err != nil { return nil, fmt.Errorf("user ctx init: %w", err) } ok := []optKind{} for o, t := range typeKeys { r, err := regexp.Compile(o) if err != nil { return nil, fmt.Errorf("user ctx init: %w", err) } ok = append( ok, optKind{ r: r, t: t, }, ) } return &userCtx{ filter: f, security: securityCtx{ tablesPolicy: s.Security.TablesPolicy, tableExceptions: func() map[string]any { excs := make(map[string]any) for _, e := range s.Security.TableExceptions { excs[e] = nil } return excs }(), }, tables: make(map[string]map[string]columnType), optKinds: ok, }, nil } func Init(r io.Reader, s InitOpts) (*MySQL, error) { uctx, err := userCtxInit(s) if err != nil { return nil, fmt.Errorf("mysql anonymizer init: %w", err) } return &MySQL{ uctx: uctx, sourceReader: r, }, nil } func (m *MySQL) Run(ctx context.Context, w io.Writer) error { ar := fsm.Init( m.sourceReader, fsm.Description{ Ctx: ctx, UserCtx: m.uctx, InitState: stateCreateSearch, States: map[fsm.StateName]fsm.State{ stateCreateSearch: { NextStates: []fsm.NextState{ { Name: stateCreateTableSearch, Switch: fsm.Switch{ Trigger: []byte("CREATE"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{' '}, }, }, DataHandler: nil, }, }, }, stateCreateTableSearch: { NextStates: []fsm.NextState{ { Name: stateCreateTableNameSearch, Switch: fsm.Switch{ Trigger: []byte("TABLE"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, }, }, stateCreateTableNameSearch: { NextStates: []fsm.NextState{ { Name: stateCreateTableName, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: nil, }, }, }, stateCreateTableName: { NextStates: []fsm.NextState{ { Name: stateFieldsDescriptionSearch, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: dhCreateTableName, }, }, }, stateFieldsDescriptionSearch: { NextStates: []fsm.NextState{ { Name: stateFieldsDescriptionBlock, Switch: fsm.Switch{ Trigger: []byte("("), }, DataHandler: nil, }, }, }, stateFieldsDescriptionBlock: { NextStates: []fsm.NextState{ { // Skip table keys description Name: stateFieldDescriptionTailSkip, Switch: fsm.Switch{ Trigger: []byte("KEY"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, { // Skip table keys description Name: stateFieldDescriptionTailSkip, Switch: fsm.Switch{ Trigger: []byte("PRIMARY"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, { // Skip table keys description Name: stateFieldDescriptionTailSkip, Switch: fsm.Switch{ Trigger: []byte("UNIQUE"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, { // Skip table keys description Name: stateFieldDescriptionTailSkip, Switch: fsm.Switch{ Trigger: []byte("CONSTRAINT"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, { // Skip table keys description Name: stateFieldDescriptionTailSkip, Switch: fsm.Switch{ Trigger: []byte("FOREIGN"), Delimiters: fsm.Delimiters{ L: []byte{' '}, R: []byte{' '}, }, }, DataHandler: nil, }, { Name: stateFieldsDescriptionName, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: nil, }, }, }, stateFieldDescriptionTailSkip: { NextStates: []fsm.NextState{ { Name: stateFieldsDescriptionBlock, Switch: fsm.Switch{ Trigger: []byte(","), Delimiters: fsm.Delimiters{ R: []byte{'\n', '\r'}, }, }, DataHandler: nil, }, { Name: statefFieldsDescriptionBlockEnd, Switch: fsm.Switch{ Trigger: []byte(")"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, }, }, DataHandler: nil, }, }, }, stateFieldsDescriptionName: { NextStates: []fsm.NextState{ { Name: stateFieldsDescriptionNameTail, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: dhCreateTableFieldName, }, }, }, stateFieldsDescriptionNameTail: { NextStates: []fsm.NextState{ { Name: stateFieldsDescriptionBlock, Switch: fsm.Switch{ Trigger: []byte(","), Delimiters: fsm.Delimiters{ R: []byte{'\n', '\r'}, }, }, DataHandler: dhCreateTableColumnAdd, }, { Name: statefFieldsDescriptionBlockEnd, Switch: fsm.Switch{ Trigger: []byte(")"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, }, }, DataHandler: dhCreateTableColumnAdd, }, }, }, statefFieldsDescriptionBlockEnd: { NextStates: []fsm.NextState{ { Name: stateSomeIntermediateState, Switch: fsm.Switch{ Trigger: []byte(";"), Delimiters: fsm.Delimiters{ R: []byte{'\n', '\r'}, }, }, DataHandler: nil, }, }, }, stateSomeIntermediateState: { NextStates: []fsm.NextState{ { Name: stateCreateTableSearch, Switch: fsm.Switch{ Trigger: []byte("CREATE"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{' '}, }, }, DataHandler: nil, }, { Name: stateInsertIntoTableNameSearch, Switch: fsm.Switch{ Trigger: []byte("INSERT INTO"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{' '}, }, }, DataHandler: dhSecurityInsertInto, }, }, }, stateInsertIntoTableNameSearch: { NextStates: []fsm.NextState{ { Name: stateInsertIntoTableName, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: dhSecurityInsertIntoTableNameSearch, }, }, }, stateInsertIntoTableName: { NextStates: []fsm.NextState{ { Name: stateValuesSearchKeyword, Switch: fsm.Switch{ Trigger: []byte("`"), }, DataHandler: dhInsertIntoTableName, }, }, }, stateValuesSearchKeyword: { NextStates: []fsm.NextState{ { Name: stateValuesSearch, Switch: fsm.Switch{ Trigger: []byte("VALUES"), Delimiters: fsm.Delimiters{ L: []byte{' ', '\n'}, R: []byte{' ', '\n', '\r'}, }, }, DataHandler: dhSecurityInsertIntoValues, }, }, }, stateValuesSearch: { NextStates: []fsm.NextState{ { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte("("), }, DataHandler: dhSecurityInsertIntoValueSearch, }, }, }, stateTableValues: { NextStates: []fsm.NextState{ { Name: stateTableValuesString, Switch: fsm.Switch{ Trigger: []byte("'"), }, DataHandler: fsm.DataHandlerGenericVoid, }, { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte(","), }, DataHandler: dhCreateTableValues, }, { Name: stateTableValuesEnd, Switch: fsm.Switch{ Trigger: []byte(")"), }, DataHandler: dhCreateTableValuesEnd, }, }, }, stateTableValuesString: { NextStates: []fsm.NextState{ { Name: stateTableValuesStringEnd, Switch: fsm.Switch{ Trigger: []byte("'"), Escape: true, }, DataHandler: dhCreateTableValuesString, }, }, }, stateTableValuesStringEnd: { NextStates: []fsm.NextState{ { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte(","), }, DataHandler: fsm.DataHandlerGenericVoid, }, { Name: stateTableValuesEnd, Switch: fsm.Switch{ Trigger: []byte(")"), }, DataHandler: dhCreateTableValuesStringEnd, }, }, }, stateTableValuesEnd: { NextStates: []fsm.NextState{ { Name: stateValuesSearch, Switch: fsm.Switch{ Trigger: []byte(","), }, DataHandler: fsm.DataHandlerGenericVoid, }, { Name: stateSomeIntermediateState, Switch: fsm.Switch{ Trigger: []byte(";"), }, DataHandler: dhSecurityValuesEnd, }, }, }, }, }, ) _, err := io.Copy(w, ar) if err != nil { return fmt.Errorf("mysql anonymizer run: %w", err) } return nil } ================================================ FILE: modules/anonymizers/mysql/mysql_test.go ================================================ package mysql_anonymize import ( "bytes" "context" "os" "testing" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" ) func TestMySQL(t *testing.T) { var r, e bytes.Buffer fin, err := os.Open(".testdata/mysql_test.in.sql") if err != nil { t.Fatal("open input SQL:", err) } m, err := Init( fin, InitOpts{ Rules: RulesOpts{ TableRules: map[string]map[string]relfilter.ColumnRuleOpts{ // Delete only row with id `2` "table1": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.id \"2\" }}{{ drop }}{{ else }}{{ .Values.id }}{{ end }}", Unique: false, }, }, // Delete all rows from table "table2": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ drop }}", Unique: false, }, }, // Delete no rows "table3": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.id \"4\" }}{{ drop }}{{ else }}{{ .Values.id }}{{ end }}", Unique: false, }, }, }, }, }, ) if err != nil { t.Fatal("init MySQL:", err) } if err := m.Run(context.Background(), &r); err != nil { t.Fatal("run MySQL:", err) } fout, err := os.Open(".testdata/mysql_test.out.sql") if err != nil { t.Fatal("open output SQL:", err) } if _, err := e.ReadFrom(fout); err != nil { t.Fatal("read output SQL:", err) } // os.WriteFile(".testdata/mysql_test.out.sql", r.Bytes(), 0644) if r.String() != e.String() { t.Fatal("incorrect anonymization result") } t.Logf("success") } func TestMySQLDos(t *testing.T) { var r, e bytes.Buffer fin, err := os.Open(".testdata/mysql_test.dos.in.sql") if err != nil { t.Fatal("open input SQL:", err) } m, err := Init( fin, InitOpts{ Rules: RulesOpts{ TableRules: map[string]map[string]relfilter.ColumnRuleOpts{ // Delete only row with id `2` "table1": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.id \"2\" }}{{ drop }}{{ else }}{{ .Values.id }}{{ end }}", Unique: false, }, }, // Delete all rows from table "table2": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ drop }}", Unique: false, }, }, // Delete no rows "table3": { "id": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.id \"4\" }}{{ drop }}{{ else }}{{ .Values.id }}{{ end }}", Unique: false, }, }, }, }, }, ) if err != nil { t.Fatal("init MySQL:", err) } if err := m.Run(context.Background(), &r); err != nil { t.Fatal("run MySQL:", err) } fout, err := os.Open(".testdata/mysql_test.dos.out.sql") if err != nil { t.Fatal("open output SQL:", err) } if _, err := e.ReadFrom(fout); err != nil { t.Fatal("read output SQL:", err) } // os.WriteFile(".testdata/mysql_test.dos.out.sql", r.Bytes(), 0644) if r.String() != e.String() { t.Fatal("incorrect anonymization result") } t.Logf("success") } ================================================ FILE: modules/anonymizers/mysql/security_types.go ================================================ package mysql_anonymize import ( "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" ) var typeRuleDefault = []relfilter.TypeRuleOpts{ // String { Selector: "(?i)^char\\((\\d+)\\)|^char", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ trunc (index .ColumnTypeGroups 0 1 | int ) \"randomized char\" }}", Unique: false, }, }, { Selector: "(?i)^varchar\\((\\d+)\\)|^varchar", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ trunc (index .ColumnTypeGroups 0 1 | int ) \"randomized varchar\" }}", Unique: false, }, }, { Selector: "(?i)^tinytext", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized tinytext", Unique: false, }, }, { Selector: "(?i)^text", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized text", Unique: false, }, }, { Selector: "(?i)^mediumtext", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized mediumtext", Unique: false, }, }, { Selector: "(?i)^longtext", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized longtext", Unique: false, }, }, { Selector: "(?i)^enum\\(.*'(.*)'.*\\)", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ index .ColumnTypeGroups 0 1 }}", Unique: false, }, }, { Selector: "(?i)^set\\(.*'(.*)'.*\\)", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ index .ColumnTypeGroups 0 1 }}", Unique: false, }, }, { Selector: "(?i)^datetime", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "2024-01-01 00:00:00", Unique: false, }, }, { Selector: "(?i)^date", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "2024-01-01", Unique: false, }, }, { Selector: "(?i)^timestamp", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "2024-01-01 00:00:00", Unique: false, }, }, { Selector: "(?i)^time", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "00:00:00", Unique: false, }, }, { Selector: "(?i)^year", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "2024", Unique: false, }, }, { Selector: "(?i)^json", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{\"randomized\": \"json_data\"}", Unique: false, }, }, // Numeric { Selector: "(?i)^bit", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^bool", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^boolean", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^tinyint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^smallint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^mediumint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^int", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^integer", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^bigint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^float", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^double", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^decimal", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^dec", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, // Binary { Selector: "(?i)^binary", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, { Selector: "(?i)^varbinary", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, { Selector: "(?i)^tinyblob", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, { Selector: "(?i)^blob", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, { Selector: "(?i)^mediumblob", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, { Selector: "(?i)^longblob", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "cmFuZG9taXplZCBiaW5hcnkgZGF0YQo=", Unique: false, }, }, } ================================================ FILE: modules/anonymizers/mysql/states.go ================================================ package mysql_anonymize import fsm "github.com/nixys/nxs-go-fsm" var ( stateCreateSearch = fsm.StateName("create search") stateCreateTableSearch = fsm.StateName("create table search") stateCreateTableNameSearch = fsm.StateName("create table name search") stateCreateTableName = fsm.StateName("create table name") stateFieldsDescriptionSearch = fsm.StateName("fields description search") stateFieldsDescriptionBlock = fsm.StateName("fields description block") stateFieldsDescriptionName = fsm.StateName("fields description name") stateFieldsDescriptionNameTail = fsm.StateName("fields description name tail") stateFieldDescriptionTailSkip = fsm.StateName("fields description tail skip") statefFieldsDescriptionBlockEnd = fsm.StateName("fields description block end") stateSomeIntermediateState = fsm.StateName("some intermediate state") stateInsertIntoTableNameSearch = fsm.StateName("insert into table name search") stateInsertIntoTableName = fsm.StateName("insert into table name") stateValuesSearch = fsm.StateName("values search") stateTableValues = fsm.StateName("table values") stateTableValuesString = fsm.StateName("table values string") stateTableValuesBinary = fsm.StateName("table values binary") stateTableValuesEnd = fsm.StateName("table values end") stateTableValuesStringEnd = fsm.StateName("table values string end") stateValuesSearchKeyword = fsm.StateName("values search key VALUES") stateFieldsGenerated = fsm.StateName("fields generated search") ) ================================================ FILE: modules/anonymizers/pgsql/.testdata/pgsql_test.dos.in.sql ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types2; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types2 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types2 OWNER TO postgres; -- -- Name: list_types3; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types3 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types3 OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; \N 42.99465 \N Biba \N \N 19:51:50+00 \N \N \N 6 \N -84.46685 \N Pupa \N \N 03:34:36+00 \N \N \N 2 \N 72.52040 \N Lupa \N 15:17:37+00 t \N \N 4 \N 99.37111 \N Boba \N 03:34:36+00 \N \N \N 8 \N -90.90125 \N Cerebla \N \N 22:00:45+00 \N \N \N 10 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types2; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types2 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types3; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types3 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: modules/anonymizers/pgsql/.testdata/pgsql_test.dos.out.sql ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types2; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types2 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types2 OWNER TO postgres; -- -- Name: list_types3; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types3 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types3 OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; \N 42.99465 \N Biba \N \N 19:51:50+00 \N \N \N 6 \N -84.46685 \N Pupa \N \N 03:34:36+00 \N \N \N 2 \N 72.52040 \N Lupa \N 15:17:37+00 t \N \N 4 \N 99.37111 \N Boba \N 03:34:36+00 \N \N \N 8 \N -90.90125 \N Cerebla \N \N 22:00:45+00 \N \N \N 10 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types2; Type: TABLE DATA; Schema: public; Owner: postgres -- -- -- Data for Name: list_types3; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types3 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: modules/anonymizers/pgsql/.testdata/pgsql_test.in.sql ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types2; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types2 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types2 OWNER TO postgres; -- -- Name: list_types3; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types3 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types3 OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; \N 42.99465 \N Biba \N \N 19:51:50+00 \N \N \N 6 \N -84.46685 \N Pupa \N \N 03:34:36+00 \N \N \N 2 \N 72.52040 \N Lupa \N 15:17:37+00 t \N \N 4 \N 99.37111 \N Boba \N 03:34:36+00 \N \N \N 8 \N -90.90125 \N Cerebla \N \N 22:00:45+00 \N \N \N 10 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types2; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types2 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types3; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types3 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: modules/anonymizers/pgsql/.testdata/pgsql_test.out.sql ================================================ -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 (Debian 16.3-1.pgdg120+1) -- Dumped by pg_dump version 16.3 (Debian 16.3-1.pgdg120+1) SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: list_types; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types OWNER TO postgres; -- -- Name: list_types2; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types2 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types2 OWNER TO postgres; -- -- Name: list_types3; Type: TABLE; Schema: public; Owner: postgres -- CREATE TABLE public.list_types3 ( integer_type integer, numeric_type numeric, double_precision_type double precision, varchar_type character varying, text_type text, date_type date, time_tz_type time with time zone, boolean_type boolean, xml_type xml, jsonb_type jsonb, id bigint NOT NULL ); ALTER TABLE public.list_types3 OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public.list_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE public.list_types_id_seq OWNER TO postgres; -- -- Name: list_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres -- ALTER SEQUENCE public.list_types_id_seq OWNED BY public.list_types.id; -- -- Name: list_types id; Type: DEFAULT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ALTER COLUMN id SET DEFAULT nextval('public.list_types_id_seq'::regclass); -- -- Data for Name: list_types; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; \N 42.99465 \N Biba \N \N 19:51:50+00 \N \N \N 6 \N -84.46685 \N Pupa \N \N 03:34:36+00 \N \N \N 2 \N 72.52040 \N Lupa \N 15:17:37+00 t \N \N 4 \N 99.37111 \N Boba \N 03:34:36+00 \N \N \N 8 \N -90.90125 \N Cerebla \N \N 22:00:45+00 \N \N \N 10 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Data for Name: list_types2; Type: TABLE DATA; Schema: public; Owner: postgres -- -- -- Data for Name: list_types3; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.list_types3 (integer_type, numeric_type, double_precision_type, varchar_type, text_type, date_type, time_tz_type, boolean_type, xml_type, jsonb_type, id) FROM stdin; 8765542 \N 7.84023409 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel pretium lectus quam id leo in vitae. Dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet aliquam id diam maecenas. Ornare lectus sit amet est placerat in egestas erat. Et malesuada fames ac turpis egestas maecenas pharetra convallis. Orci sagittis eu volutpat odio facilisis. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Nisi porta lorem mollis aliquam ut porttitor leo a diam. Amet purus gravida quis blandit turpis cursus in. Risus feugiat in ante metus. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Faucibus nisl tincidunt eget nullam. Lectus quam id leo in vitae turpis massa. Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Pretium lectus quam id leo in vitae turpis massa. Blandit aliquam etiam erat velit scelerisque in dictum non. Eu nisl nunc mi ipsum faucibus vitae. 1996-06-15 \N t \n 721744494.7994413\n -26197703.515699387\n event\n \n among\n couple\n official\n spring\n 1032613367\n \n 198858711\n {"truck": 1563128845, "little": -1009907448.0705619, "possible": "gave"} 1 4562892 \N 5.8024375 \N Massa sapien faucibus et molestie ac. Praesent elementum facilisis leo vel. Turpis egestas pretium aenean pharetra magna. Facilisi cras fermentum odio eu feugiat pretium nibh ipsum consequat. Auctor neque vitae tempus quam pellentesque. Ornare aenean euismod elementum nisi quis eleifend. Purus sit amet luctus venenatis lectus. Tortor consequat id porta nibh venenatis cras sed felis eget. Felis bibendum ut tristique et egestas quis ipsum. Pretium fusce id velit ut tortor pretium viverra. Nam aliquam sem et tortor consequat. Nisl pretium fusce id velit. Sem integer vitae justo eget magna fermentum iaculis. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat. Vitae auctor eu augue ut lectus arcu. Malesuada fames ac turpis egestas. Ac odio tempor orci dapibus ultrices in. Amet massa vitae tortor condimentum lacinia quis vel eros donec. Et malesuada fames ac turpis egestas integer. Sodales ut eu sem integer vitae justo eget. 2031-07-14 \N f \n \n -598731677.6283197\n variety\n 46234734.5525651\n rising\n -1556052082.582368\n \n eleven\n 1863692621\n -139561185.33627748\n funny\n [{"ago": {"shut": "seven", "found": 469996577.0459976, "climate": "early"}, "scene": "slightly", "medicine": true}, true, true] 3 87689278 \N -0.31813426 Id donec ultrices tincidunt arcu. Id nibh tortor id aliquet lectus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Cursus vitae congue mauris rhoncus. Eu ultrices vitae auctor eu augue ut lectus arcu bibendum. Sed turpis tincidunt id aliquet. Feugiat scelerisque varius morbi enim nunc faucibus a pellentesque sit. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. Scelerisque eu ultrices vitae auctor eu augue ut. Volutpat ac tincidunt vitae semper quis. 1976-12-10 \N t \n rise\n \n consist\n someone\n white\n victory\n -761134241.8632131\n \n 1111641157\n 744054503\n 1876042205.1417785\n {"torn": [false, -1325125579, false], "rising": false, "volume": "grow"} 9 687527896 \N -1.81914025 Facilisi etiam dignissim diam quis enim. Diam ut venenatis tellus in metus vulputate eu. Mattis rhoncus urna neque viverra justo nec ultrices. Sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nec ullamcorper sit amet risus nullam eget felis eget. Fames ac turpis egestas maecenas pharetra convallis posuere. Eget arcu dictum varius duis at consectetur lorem. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Magna fermentum iaculis eu non diam phasellus vestibulum lorem sed. Etiam non quam lacus suspendisse. Parturient montes nascetur ridiculus mus. Ornare suspendisse sed nisi lacus sed viverra tellus in. Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Urna nec tincidunt praesent semper feugiat nibh sed pulvinar. 2051-05-16 \N t \n \n 398209907.5902777\n wind\n parallel\n paint\n -1386172501\n \n previous\n skill\n conversation\n keep\n [[-128477882.56726694, 1569798072.8967233, {"us": 438307927.6373253, "think": -870063635, "product": "stuck"}], [{"name": "broad", "took": "brother", "alphabet": -731303259}, [-1065068182.0998564, "finish", "up"], false], false] 5 8767542 \N 5.08081291 \N Fames ac turpis egestas maecenas. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Sit amet commodo nulla facilisi nullam vehicula. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Maecenas ultricies mi eget mauris pharetra. Sed faucibus turpis in eu mi bibendum. Massa ultricies mi quis hendrerit dolor magna. Non diam phasellus vestibulum lorem sed. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa. Massa ultricies mi quis hendrerit dolor magna eget est lorem. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus. 2058-03-29 \N f \n concerned\n -1671936329.7007055\n slept\n how\n -1838021068\n {"basis": "mine", "company": {"tired": false, "prevent": false, "suppose": 735075799}, "worried": {"iron": 378563223.91183805, "nest": false, "raise": {"date": false, "engineer": true, "television": 136840736.65782642}}} 7 \. -- -- Name: list_types_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres -- SELECT pg_catalog.setval('public.list_types_id_seq', 10, true); -- -- Name: list_types list_types_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- ALTER TABLE ONLY public.list_types ADD CONSTRAINT list_types_pkey PRIMARY KEY (id); -- -- PostgreSQL database dump complete -- ================================================ FILE: modules/anonymizers/pgsql/dh.go ================================================ package pgsql_anonymize import ( "bytes" "fmt" "strings" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" ) func dhSecurityCopy(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) uctx.security.tmpBuf = append(uctx.security.tmpBuf, token...) uctx.insertIntoBuf = nil return deferred, nil } func dhCopyValuesEnd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } if uctx.insertIntoBuf != nil { return []byte{}, nil } return append(deferred, token...), nil } func dhCreateTableName(usrCtx any, deferred, token []byte) ([]byte, error) { tname := string(bytes.TrimSpace(deferred)) uctx := usrCtx.(*userCtx) uctx.tn = &tname return append(deferred, token...), nil } func dhCreateTableDesc(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) clmns := make(map[string]string) ss := bytes.Split(deferred, []byte{'\n'}) for _, v := range ss { s := strings.TrimSuffix(strings.TrimSpace(string(v)), ",") if len(s) > 0 { u := strings.SplitN(s, " ", 2) // If column type does not specified within the dump if len(u) < 2 { clmns[u[0]] = "" } else { clmns[u[0]] = u[1] } } } uctx.tables[*uctx.tn] = clmns uctx.tn = nil return append(deferred, token...), nil } func dhTableName(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) tname := string(bytes.TrimSpace(deferred)) if !securityPolicyCheck(uctx, tname) { // If not: table will be skipped from result dump uctx.security.isSkip = true uctx.security.tmpBuf = []byte{} return []byte{}, nil } uctx.filter.TableCreate(tname) uctx.insertIntoBuf = append(uctx.security.tmpBuf, append(deferred, token...)...) uctx.security.isSkip = false uctx.security.tmpBuf = []byte{} return []byte{}, nil } func dhFieldName(usrCtx any, deferred, token []byte) ([]byte, error) { fname := bytes.Trim(bytes.TrimSpace(deferred), "\"") uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } uctx.filter.ColumnAdd( string(fname), uctx.tables[uctx.filter.TableNameGet()][string(fname)], ) uctx.insertIntoBuf = append(uctx.insertIntoBuf, append(deferred, token...)...) return []byte{}, nil } func dhTableCopyTail(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } uctx.insertIntoBuf = append(uctx.insertIntoBuf, append(deferred, token...)...) return []byte{}, nil } func dhValue(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } s := string(deferred) if s == "\\N" { uctx.filter.ValueAdd(misc.TemplateNULL) } else { uctx.filter.ValueAdd(s) } return []byte{}, nil } func dhValueEnd(usrCtx any, deferred, token []byte) ([]byte, error) { uctx := usrCtx.(*userCtx) if uctx.security.isSkip == true { return []byte{}, nil } s := string(deferred) if s == "\\N" { uctx.filter.ValueAdd(misc.TemplateNULL) } else { uctx.filter.ValueAdd(s) } // Apply filter for row if err := uctx.filter.Apply(); err != nil { return []byte{}, err } b := rowDataGen(uctx.filter) if b == nil { return []byte{}, nil } else { if uctx.insertIntoBuf != nil { b = append(uctx.insertIntoBuf, b...) uctx.insertIntoBuf = nil } } return b, nil } func rowDataGen(filter *relfilter.Filter) []byte { var out string row := filter.ValuePop() if row.Values == nil { return nil } for i, v := range row.Values { if i > 0 { out += "\t" } if v.V == misc.TemplateNULL { out += "\\N" } else { out += fmt.Sprintf("%s", v.V) } } return fmt.Appendf([]byte(out), "\n") } // SecurityPolicyCheck checks the table passes the security rules // true: pass // false: skip func securityPolicyCheck(uctx *userCtx, tname string) bool { // Continue if security policy is `skip` if uctx.security.tablesPolicy != misc.SecurityPolicyTablesSkip { return true } // Check rules for specified table name if tr := uctx.filter.TableRulesLookup(tname); tr != nil { return true } // Check specified table name in exceptions if _, b := uctx.security.tableExceptions[tname]; b == true { return true } return false } ================================================ FILE: modules/anonymizers/pgsql/pgsql.go ================================================ package pgsql_anonymize import ( "context" "fmt" "io" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" fsm "github.com/nixys/nxs-go-fsm" ) type PgSQL struct { uctx *userCtx sourceReader io.Reader } type InitOpts struct { Variables map[string]relfilter.VariableRuleOpts Security SecurityOpts Rules RulesOpts Link []relfilter.LinkOpts } type RulesOpts struct { TableRules map[string]map[string]relfilter.ColumnRuleOpts DefaultRules map[string]relfilter.ColumnRuleOpts ExceptionColumns []string TypeRuleCustom []relfilter.TypeRuleOpts } type SecurityOpts struct { TablesPolicy misc.SecurityPolicyTablesType ColumnsPolicy misc.SecurityPolicyColumnsType TableExceptions []string } type userCtx struct { filter *relfilter.Filter tn *string security securityCtx tables map[string]map[string]string insertIntoBuf []byte } type securityCtx struct { tmpBuf []byte isSkip bool tablesPolicy misc.SecurityPolicyTablesType tableExceptions map[string]any } func userCtxInit(s InitOpts) (*userCtx, error) { f, err := relfilter.Init( relfilter.InitOpts{ Variables: s.Variables, Link: s.Link, TableRules: s.Rules.TableRules, DefaultRules: s.Rules.DefaultRules, ExceptionColumns: s.Rules.ExceptionColumns, TypeRuleCustom: s.Rules.TypeRuleCustom, TypeRuleDefault: typeRuleDefault, ColumnsPolicy: s.Security.ColumnsPolicy, }, ) if err != nil { return nil, fmt.Errorf("user ctx init: %w", err) } return &userCtx{ filter: f, security: securityCtx{ tablesPolicy: s.Security.TablesPolicy, tableExceptions: func() map[string]any { excs := make(map[string]any) for _, e := range s.Security.TableExceptions { excs[e] = nil } return excs }(), }, tables: make(map[string]map[string]string), }, nil } func Init(r io.Reader, s InitOpts) (*PgSQL, error) { uctx, err := userCtxInit(s) if err != nil { return nil, fmt.Errorf("pgsql anonymizer init: %w", err) } return &PgSQL{ uctx: uctx, sourceReader: r, }, nil } func (p *PgSQL) Run(ctx context.Context, w io.Writer) error { ar := fsm.Init( p.sourceReader, fsm.Description{ Ctx: ctx, UserCtx: p.uctx, InitState: stateInit, States: map[fsm.StateName]fsm.State{ stateInit: { NextStates: []fsm.NextState{ { Name: stateTableName, Switch: fsm.Switch{ Trigger: []byte("COPY"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{' '}, }, }, DataHandler: dhSecurityCopy, }, { Name: stateCreateTableName, Switch: fsm.Switch{ Trigger: []byte("CREATE TABLE"), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{' '}, }, }, DataHandler: nil, }, }, }, stateCreateTableName: { NextStates: []fsm.NextState{ { Name: stateCreateTableTail, Switch: fsm.Switch{ Trigger: []byte("("), Delimiters: fsm.Delimiters{ R: []byte{'\n', '\r'}, }, }, DataHandler: dhCreateTableName, }, }, }, stateCreateTableTail: { NextStates: []fsm.NextState{ { Name: stateInit, Switch: fsm.Switch{ Trigger: []byte(");"), Delimiters: fsm.Delimiters{ R: []byte{'\n', '\r'}, }, }, DataHandler: dhCreateTableDesc, }, }, }, stateTableName: { NextStates: []fsm.NextState{ { Name: stateFieldName, Switch: fsm.Switch{ Trigger: []byte("("), }, DataHandler: dhTableName, }, }, }, stateFieldName: { NextStates: []fsm.NextState{ { Name: stateFieldName, Switch: fsm.Switch{ Trigger: []byte(","), }, DataHandler: dhFieldName, }, { Name: stateCopyTail, Switch: fsm.Switch{ Trigger: []byte(")"), }, DataHandler: dhFieldName, }, }, }, stateCopyTail: { NextStates: []fsm.NextState{ { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte(";\r\n"), }, DataHandler: dhTableCopyTail, }, { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte(";\n"), }, DataHandler: dhTableCopyTail, }, }, }, stateTableValues: { NextStates: []fsm.NextState{ { Name: stateInit, Switch: fsm.Switch{ Trigger: []byte("\\."), Delimiters: fsm.Delimiters{ L: []byte{'\n'}, R: []byte{'\n', '\r'}, }, Escape: false, }, DataHandler: dhCopyValuesEnd, }, { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte{'\t'}, }, DataHandler: dhValue, }, { Name: stateTableValues, Switch: fsm.Switch{ Trigger: []byte{'\n'}, }, DataHandler: dhValueEnd, }, }, }, }, }, ) _, err := io.Copy(w, ar) if err != nil { return fmt.Errorf("pgsql anonymizer run: %w", err) } return nil } ================================================ FILE: modules/anonymizers/pgsql/pgsql_test.go ================================================ package pgsql_anonymize import ( "bytes" "context" "os" "testing" "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" ) func TestPgSQL(t *testing.T) { var r, e bytes.Buffer fin, err := os.Open(".testdata/pgsql_test.in.sql") if err != nil { t.Fatal("open input SQL:", err) } m, err := Init( fin, InitOpts{ Rules: RulesOpts{ TableRules: map[string]map[string]relfilter.ColumnRuleOpts{ // Delete only row with id `2` "public.list_types": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.integer_type \"8765542\" }}{{ drop }}{{ else }}{{ .Values.integer_type }}{{ end }}", Unique: false, }, }, // Delete all rows from table "public.list_types2": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ drop }}", Unique: false, }, }, // Delete no rows "public.list_types3": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.integer_type \"0\" }}{{ drop }}{{ else }}{{ .Values.integer_type }}{{ end }}", Unique: false, }, }, }, }, }, ) if err != nil { t.Fatal("init PgSQL:", err) } if err := m.Run(context.Background(), &r); err != nil { t.Fatal("run PgSQL:", err) } fout, err := os.Open(".testdata/pgsql_test.out.sql") if err != nil { t.Fatal("open output SQL:", err) } if _, err := e.ReadFrom(fout); err != nil { t.Fatal("read output SQL:", err) } // os.WriteFile(".testdata/pgsql_test.out.sql", r.Bytes(), 0644) if r.String() != e.String() { t.Fatal("incorrect anonymization result") } t.Logf("success") } func TestPgSQLDos(t *testing.T) { var r, e bytes.Buffer fin, err := os.Open(".testdata/pgsql_test.dos.in.sql") if err != nil { t.Fatal("open input SQL:", err) } m, err := Init( fin, InitOpts{ Rules: RulesOpts{ TableRules: map[string]map[string]relfilter.ColumnRuleOpts{ // Delete only row with id `2` "public.list_types": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.integer_type \"8765542\" }}{{ drop }}{{ else }}{{ .Values.integer_type }}{{ end }}", Unique: false, }, }, // Delete all rows from table "public.list_types2": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ drop }}", Unique: false, }, }, // Delete no rows "public.list_types3": { "integer_type": relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{ if eq .Values.integer_type \"0\" }}{{ drop }}{{ else }}{{ .Values.integer_type }}{{ end }}", Unique: false, }, }, }, }, }, ) if err != nil { t.Fatal("init PgSQL:", err) } if err := m.Run(context.Background(), &r); err != nil { t.Fatal("run PgSQL:", err) } fout, err := os.Open(".testdata/pgsql_test.dos.out.sql") if err != nil { t.Fatal("open output SQL:", err) } if _, err := e.ReadFrom(fout); err != nil { t.Fatal("read output SQL:", err) } // os.WriteFile(".testdata/pgsql_test.dos.out.sql", r.Bytes(), 0644) if r.String() != e.String() { t.Fatal("incorrect anonymization result") } t.Logf("success") } ================================================ FILE: modules/anonymizers/pgsql/security_types.go ================================================ package pgsql_anonymize import ( "github.com/nixys/nxs-data-anonymizer/misc" "github.com/nixys/nxs-data-anonymizer/modules/filters/relfilter" ) var typeRuleDefault = []relfilter.TypeRuleOpts{ // Integer { Selector: "(?i)^boolean", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^smallint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^integer", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^bigint", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^smallserial", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^serial", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, { Selector: "(?i)^bigserial", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0", Unique: false, }, }, // Float { Selector: "(?i)^decimal", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^numeric", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^real", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, { Selector: "(?i)^double", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "0.0", Unique: false, }, }, // Strings { Selector: "(?i)^character", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized character data", Unique: false, }, }, { Selector: "(?i)^bpchar", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized bpchar data", Unique: false, }, }, { Selector: "(?i)^text", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "randomized text data", Unique: false, }, }, // Date & time { Selector: "(?i)^date", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "2024-01-01", Unique: false, }, }, { Selector: "(?i)^time", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "00:00:00", Unique: false, }, }, // Structures { Selector: "(?i)^jsonb", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{\"randomized\": \"json_data\"}", Unique: false, }, }, { Selector: "(?i)^xml", Rule: relfilter.ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "Randomized XML", Unique: false, }, }, } ================================================ FILE: modules/anonymizers/pgsql/states.go ================================================ package pgsql_anonymize import fsm "github.com/nixys/nxs-go-fsm" var ( stateInit = fsm.StateName("init") stateCreateTableName = fsm.StateName("create table name") stateCreateTableTail = fsm.StateName("create table tail") stateTableName = fsm.StateName("table name") stateFieldName = fsm.StateName("field name") stateCopyTail = fsm.StateName("copy tail") stateTableValues = fsm.StateName("table values") ) ================================================ FILE: modules/filters/relfilter/column.go ================================================ package relfilter import "fmt" type columns struct { cc []*column m map[string]*column } type column struct { n string t columnTypes } type columnTypes struct { raw string groups [][]string r *ColumnRuleOpts env []string } func columnsInit() columns { return columns{ cc: []*column{}, m: make(map[string]*column), } } func (c *columns) add(name string, rt string, pts [][]string, r *ColumnRuleOpts) { env := []string{fmt.Sprintf("%s=%s", envVarColumnTypeRAW, rt)} for i, g := range pts { for j, sg := range g { if j == 0 { env = append( env, fmt.Sprintf("%s%d=%s", envVarColumnTypeGroupPrefix, i, sg), ) } else { env = append( env, fmt.Sprintf("%s%d_%d=%s", envVarColumnTypeGroupPrefix, i, j-1, sg), ) } } } v := column{ n: name, t: columnTypes{ raw: rt, groups: pts, r: r, env: env, }, } c.cc = append(c.cc, &v) c.m[name] = &v } func (c *columns) getNameByIndex(index int) string { if index >= len(c.cc) { return "" } return c.cc[index].n } func (c *columns) delByName(name string) { // Get current column element v := c.m[name] // Delete element from map delete(c.m, name) // Delete element from slice for k, e := range c.cc { if e == v { c.cc = append(c.cc[:k], c.cc[k+1:]...) break } } } ================================================ FILE: modules/filters/relfilter/filter.go ================================================ package relfilter import ( "bytes" "fmt" "os/exec" "regexp" "strings" "github.com/nixys/nxs-data-anonymizer/misc" ) type InitOpts struct { Variables map[string]VariableRuleOpts Link []LinkOpts TableRules map[string]map[string]ColumnRuleOpts DefaultRules map[string]ColumnRuleOpts ExceptionColumns []string ColumnsPolicy misc.SecurityPolicyColumnsType TypeRuleCustom []TypeRuleOpts TypeRuleDefault []TypeRuleOpts } type TypeRuleOpts struct { Selector string Rule ColumnRuleOpts } type ColumnRuleOpts struct { Type misc.ValueType Value string Unique bool } type VariableRuleOpts struct { Type misc.ValueType Value string } type LinkOpts struct { Rule ColumnRuleOpts With map[string][]string } type Filter struct { // Rules for filter a table values rules rules // Temp table data for filtering tableData tableData } type Row struct { Values []rowValue } type rules struct { variables map[string]string tableRules map[string]map[string]ColumnRuleOpts defaultRules map[string]ColumnRuleOpts exceptionColumns map[string]any columnsPolicy misc.SecurityPolicyColumnsType typeRuleCustom []typeRule typeRuleDefault []typeRule link []linkValues } type typeRule struct { Rgx *regexp.Regexp Rule ColumnRuleOpts } type tableData struct { name string columns columns values []rowValue uniques map[string]map[string]any } type rowValue struct { V string } type linkValues struct { // Linked tables and columns t map[string]map[string]any // Map old:new values v map[string]string // Unique map u map[string]any // Rule r ColumnRuleOpts } type execFilterOpts struct { t misc.ValueType v string } const uniqueAttempts = 5 const ( envVarGlobalPrefix = "ENVVARGLOBAL_" envVarTable = "ENVVARTABLE" envVarColumnPrefix = "ENVVARCOLUMN_" envVarCurColumn = "ENVVARCURCOLUMN" envVarColumnTypeRAW = "ENVVARCOLUMNTYPERAW" envVarColumnTypeGroupPrefix = "ENVVARCOLUMNTYPEGROUP_" ) type applyRule struct { c *column i int cr ColumnRuleOpts lv map[string]string u map[string]any } func Init(opts InitOpts) (*Filter, error) { trc := []typeRule{} trd := []typeRule{} // Make custom type rules for _, r := range opts.TypeRuleCustom { re, err := regexp.Compile(r.Selector) if err != nil { return nil, fmt.Errorf("filter init: %w", err) } trc = append( trc, typeRule{ Rgx: re, Rule: r.Rule, }, ) } // Make default type rules for _, r := range opts.TypeRuleDefault { re, err := regexp.Compile(r.Selector) if err != nil { return nil, fmt.Errorf("filter init: %w", err) } trd = append( trd, typeRule{ Rgx: re, Rule: r.Rule, }, ) } // Make exceptions excpts := make(map[string]any) for _, e := range opts.ExceptionColumns { excpts[e] = nil } vars := make(map[string]string) for n, f := range opts.Variables { v, _, err := execFilter( execFilterOpts{ t: f.Type, v: f.Value, }, nil, nil, ) if err != nil { return nil, fmt.Errorf("filter init: %w", err) } vars[n] = v } lvs := []linkValues{} // Make links for _, l := range opts.Link { lv := linkValues{ t: make(map[string]map[string]any), v: make(map[string]string), u: func() map[string]any { if l.Rule.Unique { return make(map[string]any) } return nil }(), r: l.Rule, } for t, cs := range l.With { m := make(map[string]any) for _, c := range cs { m[c] = nil } lv.t[t] = m } lvs = append(lvs, lv) } return &Filter{ rules: rules{ variables: vars, link: lvs, tableRules: opts.TableRules, defaultRules: opts.DefaultRules, exceptionColumns: excpts, typeRuleCustom: trc, typeRuleDefault: trd, columnsPolicy: opts.ColumnsPolicy, }, }, nil } // TableCreate creates new data set for table `name` func (filter *Filter) TableCreate(name string) { filter.tableData = tableData{ name: name, columns: columnsInit(), uniques: make(map[string]map[string]any), values: []rowValue{}, } } func (filter *Filter) TableNameGet() string { return filter.tableData.name } // TableRulesLookup looks up filters for specified table name func (filter *Filter) TableRulesLookup(name string) map[string]ColumnRuleOpts { if t, b := filter.rules.tableRules[name]; b { return t } return nil } // ColumnAdd adds new column into current data set func (filter *Filter) ColumnAdd(name string, rt string) { //var rl *ColumnRuleOpts for _, r := range filter.rules.typeRuleCustom { gd := r.Rgx.FindAllStringSubmatch(rt, -1) if len(gd) > 0 { filter.tableData.columns.add(name, rt, gd, &r.Rule) return } } for _, r := range filter.rules.typeRuleDefault { gd := r.Rgx.FindAllStringSubmatch(rt, -1) if len(gd) > 0 { filter.tableData.columns.add(name, rt, gd, &r.Rule) return } } filter.tableData.columns.add(name, rt, nil, nil) } func (filter *Filter) ColumnGetName(index int) string { return filter.tableData.columns.getNameByIndex(index) } func (filter *Filter) ValueAdd(b string) { filter.tableData.values = append( filter.tableData.values, rowValue{ V: b, }, ) } // ValuePop pops the last values row from current data set func (filter *Filter) ValuePop() Row { // Save current values r := filter.tableData.values filter.rowCleanup() return Row{ Values: r, } } func (filter *Filter) Apply() error { var rls []applyRule tname := filter.tableData.name // Check rules exist for current table tr := filter.TableRulesLookup(tname) // Create rules for every column within current table for i, c := range filter.tableData.columns.cc { // Check linked column t := false for _, l := range filter.rules.link { if e, b := l.t[tname]; b == true { if _, u := e[c.n]; u == true { rls = append( rls, applyRule{ c: c, i: i, cr: l.r, lv: l.v, u: l.u, }, ) t = true break } } } if t { continue } // Check direct rules for column if tr != nil { if cr, e := tr[c.n]; e { rls = append( rls, applyRule{ c: c, i: i, cr: cr, }, ) continue } } // Check default rules for column if cr, e := filter.rules.defaultRules[c.n]; e { rls = append( rls, applyRule{ c: c, i: i, cr: cr, }, ) continue } // Check column is excepted if _, b := filter.rules.exceptionColumns[c.n]; b { continue } // Other rules if required // Default rules for types if filter.rules.columnsPolicy == misc.SecurityPolicyColumnsRandomize { if c.t.r != nil { rls = append( rls, applyRule{ c: c, i: i, cr: *c.t.r, }, ) } } } // Apply rules if err := filter.applyRules(tname, rls); err != nil { return fmt.Errorf("filters apply: %w", err) } return nil } func (filter *Filter) applyRules(tname string, rls []applyRule) error { // If no columns has rules if len(rls) == 0 { return nil } valEnvGlob := []string{} for n, v := range filter.rules.variables { valEnvGlob = append( valEnvGlob, fmt.Sprintf("%s%s=%s", envVarGlobalPrefix, n, v), ) } valOld := make(map[string]string) valEnvOld := []string{} for i, c := range filter.tableData.columns.cc { valOld[c.n] = filter.tableData.values[i].V // Set env var only for columns with non-nil values valEnvOld = append( valEnvOld, fmt.Sprintf("%s%s=%s", envVarColumnPrefix, c.n, filter.tableData.values[i].V), ) } // Apply rule for each specified column for _, r := range rls { var ( v string d bool err error ) if r.lv != nil { // For linked columns td := struct { Variables map[string]string }{ Variables: filter.rules.variables, } if vo := valOld[r.c.n]; vo == misc.TemplateNULL { // If old value for this cell is NULL v, d, err = filter.applyLinkFilter(r.c.n, r.cr, r.u, td, valEnvGlob) if err != nil { return fmt.Errorf("rules: %w", err) } if d { filter.tableData.values = nil return nil } } else { // Check linked value for this column already exist if e, b := r.lv[vo]; b { v = e } else { v, d, err = filter.applyLinkFilter(r.c.n, r.cr, r.u, td, valEnvGlob) if err != nil { return fmt.Errorf("rules: %w", err) } if d { filter.tableData.values = nil return nil } r.lv[vo] = v } } } else { type tplData struct { TableName string CurColumnName string Values map[string]string Variables map[string]string ColumnTypeRaw string ColumnTypeGroups [][]string } td := tplData{ TableName: tname, CurColumnName: r.c.n, Values: valOld, Variables: filter.rules.variables, ColumnTypeRaw: r.c.t.raw, ColumnTypeGroups: r.c.t.groups, } tde := []string{ fmt.Sprintf("%s=%s", envVarTable, tname), fmt.Sprintf("%s=%s", envVarCurColumn, r.c.n), } tde = append(tde, valEnvOld...) tde = append(tde, valEnvGlob...) tde = append(tde, r.c.t.env...) v, d, err = filter.applyColumnFilter(r.c.n, r.cr, td, tde) if err != nil { return fmt.Errorf("rules: %w", err) } if d { filter.tableData.values = nil return nil } } // Set specified value in accordance with filter filter.tableData.values[r.i].V = v } return nil } func (filter *Filter) applyColumnFilter(cn string, cr ColumnRuleOpts, td any, tde []string) (string, bool, error) { for i := 0; i < uniqueAttempts; i++ { v, d, err := execFilter( execFilterOpts{ t: cr.Type, v: cr.Value, }, td, tde) if err != nil { return "", false, fmt.Errorf("apply filter: %w", err) } if d { return "", true, nil } if v == misc.TemplateNULL { return v, false, nil } if !cr.Unique { return v, false, nil } var uv map[string]any if _, b := filter.tableData.uniques[cn]; !b { // For first values uv = make(map[string]any) } else { uv = filter.tableData.uniques[cn] } if _, b := uv[v]; !b { uv[v] = nil filter.tableData.uniques[cn] = uv return v, false, nil } } return "", false, fmt.Errorf("filter: unable to generate unique value for column `%s.%s`, check filter value for this column in config", filter.tableData.name, cn) } func (filter *Filter) applyLinkFilter(cn string, cr ColumnRuleOpts, u map[string]any, td any, tde []string) (string, bool, error) { for i := 0; i < uniqueAttempts; i++ { v, d, err := execFilter( execFilterOpts{ t: cr.Type, v: cr.Value, }, td, tde) if err != nil { return "", false, fmt.Errorf("apply link filter: %w", err) } if d { return "", true, nil } if v == misc.TemplateNULL { return v, false, nil } if cr.Unique == false { return v, false, nil } if _, b := u[v]; b == false { u[v] = nil return v, false, nil } } return "", false, fmt.Errorf("apply link filter: unable to generate unique value for column `%s.%s`, check filter value for this column in config", filter.tableData.name, cn) } // rowCleanup cleanups current row values func (filter *Filter) rowCleanup() { filter.tableData.values = []rowValue{} } func execFilter(f execFilterOpts, td any, tde []string) (string, bool, error) { var ( r string d bool err error ) switch f.t { case misc.ValueTypeTemplate: var t misc.TemlateRes t, err = misc.TemplateExec( f.v, td, ) if err != nil { return "", false, fmt.Errorf("filter: value compile template: %w", err) } r = t.Value d = t.DropRow case misc.ValueTypeCommand: var stderr, stdout bytes.Buffer parsed_cmd := strings.Split(f.v, " ") name := parsed_cmd[0] args := parsed_cmd[1:] cmd := exec.Command(name, args...) cmd.Stdout = &stdout cmd.Stderr = &stderr cmd.Env = tde if err := cmd.Run(); err != nil { e, b := err.(*exec.ExitError) if b == false { return "", false, fmt.Errorf("filter: value exec command: %w", err) } return "", false, fmt.Errorf("filter: value exec command: bad exit code %d: %s", e.ExitCode(), stderr.String()) } r = stdout.String() default: return "", false, fmt.Errorf("filter: value compile: unknown type") } return strings.ReplaceAll(r, "\n", "\\n"), d, nil } ================================================ FILE: modules/filters/relfilter/filter_test.go ================================================ package relfilter import ( "testing" "github.com/nixys/nxs-data-anonymizer/misc" ) func TestExecFilter(t *testing.T) { // Test `drop` template function v, d, err := execFilter( execFilterOpts{ t: misc.ValueTypeTemplate, v: "{{- drop -}}", }, nil, nil) if err != nil { t.Fatal("`drop` function:", err) } if v != "" || d == false { t.Fatal("`drop` function: incorrect return value") } t.Logf("`drop` function: success") // Test `null` template function v, d, err = execFilter( execFilterOpts{ t: misc.ValueTypeTemplate, v: "{{- null -}}", }, nil, nil) if err != nil { t.Fatal("`null` function:", err) } if v != misc.TemplateNULL || d == true { t.Fatal("`null` function: incorrect return value") } t.Logf("`null` function: success") } func TestFilterApply(t *testing.T) { TestFilterApplyDropFunction(t) TestFilterApplyNullFunction(t) TestLinkFilterApplyDropFunction(t) } func TestFilterApplyDropFunction(t *testing.T) { f, err := Init( InitOpts{ TableRules: map[string]map[string]ColumnRuleOpts{ "testTable": { "testColumn1": ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- drop -}}", Unique: false, }, }, }, }, ) if err != nil { t.Fatal("init:", err) } testFilterTableInit(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r := f.ValuePop() if r.Values != nil { t.Fatal("`drop` function: unexpected behaviour") } t.Logf("`drop` function: success") } func TestFilterApplyNullFunction(t *testing.T) { f, err := Init( InitOpts{ TableRules: map[string]map[string]ColumnRuleOpts{ "testTable": { "testColumn1": ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- null -}}", Unique: false, }, }, }, }, ) if err != nil { t.Fatal("init:", err) } testFilterTableInit(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r := f.ValuePop() if len(r.Values) < 2 || r.Values[0].V != misc.TemplateNULL { t.Fatal("`null` function: unexpected behaviour") } t.Logf("`null` function: success") } func TestLinkFilterApply(t *testing.T) { f, err := Init( InitOpts{ TableRules: map[string]map[string]ColumnRuleOpts{ "testTable1": { "testColumn1": ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- 11 -}}", Unique: false, }, }, "testTable2": { "testColumn1": ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- 22 -}}", Unique: false, }, }, }, Link: []LinkOpts{ { Rule: ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- uuidv4 -}}", Unique: false, }, With: map[string][]string{ "testTable1": { "testColumn2", }, "testTable2": { "testColumn2", }, }, }, }, }, ) if err != nil { t.Fatal("init:", err) } // Fill table 1 testLinkFilterTable1Init(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r1 := f.ValuePop() if len(r1.Values) < 2 { t.Fatal("incorrect row len for table 1") } if r1.Values[1].V == misc.TemplateNULL { t.Fatal("NULL cell value in table 1") } v1 := r1.Values[1].V // Fill table 2 testLinkFilterTable2Init(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r2 := f.ValuePop() if len(r2.Values) < 2 { t.Fatal("incorrect row len for table 2") } if r2.Values[1].V == misc.TemplateNULL { t.Fatal("NULL cell value in table 2") } v2 := r2.Values[1].V if v1 != v2 { t.Fatal("incorrect values for tables after filter apply") } t.Logf("success") } func TestLinkFilterApplyDropFunction(t *testing.T) { f, err := Init( InitOpts{ TableRules: map[string]map[string]ColumnRuleOpts{ "testTable1": { "testColumn1": ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- 1 -}}", Unique: false, }, }, }, Link: []LinkOpts{ { Rule: ColumnRuleOpts{ Type: misc.ValueTypeTemplate, Value: "{{- drop -}}", Unique: false, }, With: map[string][]string{ "testTable1": { "testColumn2", }, "testTable2": { "testColumn2", }, }, }, }, }, ) if err != nil { t.Fatal("init:", err) } // Fill table 1 testLinkFilterTable1Init(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r1 := f.ValuePop() if r1.Values != nil { t.Fatal("`drop` function: unexpected behaviour for table 1") } // Fill table 2 testLinkFilterTable2Init(f) // Apply filters for row if err := f.Apply(); err != nil { t.Fatal("apply:", err) } // Get row values r2 := f.ValuePop() if r2.Values != nil { t.Fatal("`drop` function: unexpected behaviour for table 2") } t.Logf("`drop` function: success") } func testFilterTableInit(f *Filter) { // Create table f.TableCreate("testTable") // Add column `testColumn1` with value f.ColumnAdd("testColumn1", "int") f.ValueAdd("0") // Add column `testColumn2` with value f.ColumnAdd("testColumn2", "varchar(10)") f.ValueAdd("a") } func testLinkFilterTable1Init(f *Filter) { // Create table f.TableCreate("testTable1") // Add column `testColumn1` with value f.ColumnAdd("testColumn1", "int") f.ValueAdd("1") // Add column `testColumn2` with value f.ColumnAdd("testColumn2", "varchar(100)") f.ValueAdd("a") } func testLinkFilterTable2Init(f *Filter) { // Create table f.TableCreate("testTable2") // Add column `testColumn1` with value f.ColumnAdd("testColumn1", "int") f.ValueAdd("2") // Add column `testColumn2` with value f.ColumnAdd("testColumn2", "varchar(100)") f.ValueAdd("a") } ================================================ FILE: modules/progress_reader/progress_reader.go ================================================ package progressreader import "io" type ProgressReader struct { // Source reader r io.Reader // Total read bytes tb int64 } func Init(r io.Reader) *ProgressReader { return &ProgressReader{ r: r, tb: 0, } } func (pr *ProgressReader) Read(dst []byte) (int, error) { // Proxy data from source reader to anonymizer n, err := pr.r.Read(dst) // Save read bytes count pr.tb += int64(n) return n, err } // Bytes returns total read bytes from source reader func (pr *ProgressReader) Bytes() int64 { return pr.tb } ================================================ FILE: routines/anonymizer/anonymizer.go ================================================ package anonymizer import ( "context" "io" "strconv" "time" "github.com/docker/go-units" "github.com/nixys/nxs-data-anonymizer/ctx" "github.com/nixys/nxs-data-anonymizer/interfaces" "github.com/sirupsen/logrus" appctx "github.com/nixys/nxs-go-appctx/v3" ) type anonymizeOpts struct { c context.Context l *logrus.Logger ch chan error db ctx.DBCtx w io.Writer a interfaces.Anonymizer } func Runtime(app appctx.App) error { var ( // Bytes count printed in log last time lb int64 // Timer to print log read bytes count timer *time.Timer ) cc := app.ValueGet().(*ctx.Ctx) cx, cf := context.WithCancel(app.SelfCtx()) defer cf() ch := make(chan error, 1) timer = time.NewTimer(cc.Progress.Rhythm) if cc.Progress.Rhythm == 0 { if !timer.Stop() { <-timer.C } } if err := anonymize( anonymizeOpts{ c: cx, l: cc.Log, ch: ch, db: cc.DB, w: cc.Output, a: cc.Anonymizer, }, ); err != nil { return err } for { select { case <-app.SelfCtxDone(): // Log reader progress if necessary if cc.Progress.Rhythm != 0 && lb != cc.PR.Bytes() { progressLog(cc.Log, cc.PR.Bytes(), cc.Progress.Humanize) } cc.Log.Info("anonymizer routine done") return nil case err := <-ch: // Log reader progress if necessary if cc.Progress.Rhythm != 0 && lb != cc.PR.Bytes() { progressLog(cc.Log, cc.PR.Bytes(), cc.Progress.Humanize) } if err != nil { cc.Log.WithFields(logrus.Fields{ "details": err, }).Errorf("anonymize") return err } cc.Log.Info("anonymizer routine done") return nil case <-timer.C: // Save bytes count printed in log last time lb = cc.PR.Bytes() // Log reader progress progressLog(cc.Log, lb, cc.Progress.Humanize) timer.Reset(cc.Progress.Rhythm) } } } func anonymize(st anonymizeOpts) error { if st.db.Type == ctx.DBTypeMySQL && st.db.Cleanup == true && st.db.MySQL != nil { if err := st.db.MySQL.DBCleanup(); err != nil { st.l.WithFields(logrus.Fields{ "details": err, }).Errorf("anonymize: MySQL clean up") return err } } go func() { st.ch <- st.a.Run(st.c, st.w) }() return nil } func progressLog(l *logrus.Logger, b int64, h bool) { var s string // Prepare output bytes string if h == true { s = units.BytesSize(float64(b)) } else { s = strconv.FormatInt(b, 10) } l.WithFields( logrus.Fields{ "read bytes": s, }, ).Info("anonymization progress") }