nt-fingerprint 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9def9ac1a0781ac26a8de4ec3c045419d32b04914d9017b24b24bc05406eff69
4
+ data.tar.gz: e8e53e0a6378ab8153eefecf1f837a73bb2472e77f6761f65ef6eda365740165
5
+ SHA512:
6
+ metadata.gz: '08462d0f676c1ffee6d223b90c466b065db3e4923c808d4d65d784ade79623c19a64a49326bedc806e23d6d818b66594754305dfd0bcb68500353202b31c213e'
7
+ data.tar.gz: ee10cb0ad7700e195fe5a692be2b5c8a4e72316cf740748a1456fc69858cf272684e8fd58cd519e1bac4e17771a6af08a8361b1f2c1a3800e18d9935571ae9e5
@@ -0,0 +1,34 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+ workflow_dispatch:
9
+
10
+ defaults:
11
+ run:
12
+ shell: bash
13
+
14
+ jobs:
15
+ run_rspec:
16
+ name: Run Rspec on ${{ matrix.os }} with ${{ matrix.ruby-version }}
17
+ runs-on: ${{ matrix.os }}
18
+ strategy:
19
+ matrix:
20
+ os: [ubuntu-latest, macos-latest]
21
+ ruby-version: ['2.7', '3.0']
22
+
23
+ steps:
24
+ - uses: actions/checkout@v2
25
+ - name: Set up Ruby
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+ bundler-cache: true
30
+ - name: Run RSpec
31
+ run: |
32
+ gem install bundler
33
+ bundle install --jobs 4 --retry 3
34
+ bundle exec rspec
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ NewCops: enable
data/.rubocop_todo.yml ADDED
File without changes
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## [0.1.0] - 2021-02-12
2
+
3
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2021, Nayuta Yanagisawa
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Makefile ADDED
@@ -0,0 +1,12 @@
1
+ build: go/libfp.go
2
+ xgo --targets="linux/amd64,darwin/amd64" \
3
+ --buildmode=c-shared \
4
+ --out=libfp \
5
+ --dest=go/build \
6
+ github.com/nayuta-yanagisawa/nt-fingerprint/go
7
+
8
+ test:
9
+ bundle exec rspec
10
+
11
+ format:
12
+ bundle exec rubocop --auto-correct
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # nt-fingerprint
2
+
3
+ ![test](https://github.com/nayuta-yanagisawa/nt-fingerprint/workflows/test/badge.svg)
4
+
5
+ ## Synopsis
6
+
7
+ nt-fingerprint is a Ruby gem for converting queries into fingerprints.
8
+
9
+ ```ruby
10
+ require 'nt/fingerprint'
11
+
12
+ class Sample
13
+ include Nt::Fingerprint
14
+ end
15
+
16
+ puts Sample.new.fingerprint("SELECT a, b, 'c' FROM t WEHERE a = 1 AND b IN (1, 2, 3)")
17
+ # => select a, b, ? from t wehere a = ? and b in(?+)
18
+ ```
19
+
20
+ nt-fingerprint exposes a single method `fingerprint`. What the method does is just calling a function `query.Fingerprint` of [percona/go-mysql](https://github.com/percona/go-mysql) via FFI. Thus, the behavior of `fingerprint` completely follows that of `query.Fingerprint`. We quote the description of `query.Fingerprint` from the [documentation](https://pkg.go.dev/github.com/percona/go-mysql@v0.0.0-20200630114833-b77f37c0bfa2/query#Fingerprint) of go-mysql.
21
+
22
+ > ```
23
+ > func Fingerprint(q string) string
24
+ > ```
25
+ > Fingerprint returns the canonical form of q. The primary transformations are:
26
+ > ```
27
+ > - Replace values with ?
28
+ > - Collapse whitespace
29
+ > - Remove comments
30
+ > - Lowercase everything
31
+ > ```
32
+ > Additional trasnformations are performed which change the syntax of the original query without affecting its performance characteristics. For example, "ORDER BY col ASC" is the same as "ORDER BY col", so "ASC" in the fingerprint is removed.
33
+
34
+ ## Examples
35
+
36
+ A typical use case of nt-fingerprint is query logging. Using nt-fingerprint, one can exclude sensitive information from queries. This makes it possible to log production queries while maintaining security.
37
+
38
+ For example, one can capture arbitrary ActiveRecord queries by combining [Arproxy](https://github.com/cookpad/arproxy) and nt-fingerprint.
39
+
40
+ ```ruby
41
+ class QueryLogger < Arproxy::Base
42
+ include Nt::Fingerprint
43
+
44
+ def execute(sql, name=nil)
45
+ Rails.logger.info(fingerprint(sql))
46
+ super(sql, name)
47
+ end
48
+ end
49
+
50
+ Arproxy.configure do |config|
51
+ config.use QueryLogger
52
+ end
53
+ ```
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
@@ -0,0 +1,76 @@
1
+ /* Code generated by cmd/cgo; DO NOT EDIT. */
2
+
3
+ /* package github.com/nayuta-yanagisawa/nt-fingerprint/go */
4
+
5
+
6
+ #line 1 "cgo-builtin-export-prolog"
7
+
8
+ #include <stddef.h> /* for ptrdiff_t below */
9
+
10
+ #ifndef GO_CGO_EXPORT_PROLOGUE_H
11
+ #define GO_CGO_EXPORT_PROLOGUE_H
12
+
13
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
14
+ typedef struct { const char *p; ptrdiff_t n; } _GoString_;
15
+ #endif
16
+
17
+ #endif
18
+
19
+ /* Start of preamble from import "C" comments. */
20
+
21
+
22
+
23
+
24
+ /* End of preamble from import "C" comments. */
25
+
26
+
27
+ /* Start of boilerplate cgo prologue. */
28
+ #line 1 "cgo-gcc-export-header-prolog"
29
+
30
+ #ifndef GO_CGO_PROLOGUE_H
31
+ #define GO_CGO_PROLOGUE_H
32
+
33
+ typedef signed char GoInt8;
34
+ typedef unsigned char GoUint8;
35
+ typedef short GoInt16;
36
+ typedef unsigned short GoUint16;
37
+ typedef int GoInt32;
38
+ typedef unsigned int GoUint32;
39
+ typedef long long GoInt64;
40
+ typedef unsigned long long GoUint64;
41
+ typedef GoInt64 GoInt;
42
+ typedef GoUint64 GoUint;
43
+ typedef __SIZE_TYPE__ GoUintptr;
44
+ typedef float GoFloat32;
45
+ typedef double GoFloat64;
46
+ typedef float _Complex GoComplex64;
47
+ typedef double _Complex GoComplex128;
48
+
49
+ /*
50
+ static assertion to make sure the file is being used on architecture
51
+ at least with matching size of GoInt.
52
+ */
53
+ typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
54
+
55
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
56
+ typedef _GoString_ GoString;
57
+ #endif
58
+ typedef void *GoMap;
59
+ typedef void *GoChan;
60
+ typedef struct { void *t; void *v; } GoInterface;
61
+ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
62
+
63
+ #endif
64
+
65
+ /* End of boilerplate cgo prologue. */
66
+
67
+ #ifdef __cplusplus
68
+ extern "C" {
69
+ #endif
70
+
71
+
72
+ extern char* fingerprint(char* p0);
73
+
74
+ #ifdef __cplusplus
75
+ }
76
+ #endif
@@ -0,0 +1,76 @@
1
+ /* Code generated by cmd/cgo; DO NOT EDIT. */
2
+
3
+ /* package github.com/nayuta-yanagisawa/nt-fingerprint/go */
4
+
5
+
6
+ #line 1 "cgo-builtin-export-prolog"
7
+
8
+ #include <stddef.h> /* for ptrdiff_t below */
9
+
10
+ #ifndef GO_CGO_EXPORT_PROLOGUE_H
11
+ #define GO_CGO_EXPORT_PROLOGUE_H
12
+
13
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
14
+ typedef struct { const char *p; ptrdiff_t n; } _GoString_;
15
+ #endif
16
+
17
+ #endif
18
+
19
+ /* Start of preamble from import "C" comments. */
20
+
21
+
22
+
23
+
24
+ /* End of preamble from import "C" comments. */
25
+
26
+
27
+ /* Start of boilerplate cgo prologue. */
28
+ #line 1 "cgo-gcc-export-header-prolog"
29
+
30
+ #ifndef GO_CGO_PROLOGUE_H
31
+ #define GO_CGO_PROLOGUE_H
32
+
33
+ typedef signed char GoInt8;
34
+ typedef unsigned char GoUint8;
35
+ typedef short GoInt16;
36
+ typedef unsigned short GoUint16;
37
+ typedef int GoInt32;
38
+ typedef unsigned int GoUint32;
39
+ typedef long long GoInt64;
40
+ typedef unsigned long long GoUint64;
41
+ typedef GoInt64 GoInt;
42
+ typedef GoUint64 GoUint;
43
+ typedef __SIZE_TYPE__ GoUintptr;
44
+ typedef float GoFloat32;
45
+ typedef double GoFloat64;
46
+ typedef float _Complex GoComplex64;
47
+ typedef double _Complex GoComplex128;
48
+
49
+ /*
50
+ static assertion to make sure the file is being used on architecture
51
+ at least with matching size of GoInt.
52
+ */
53
+ typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
54
+
55
+ #ifndef GO_CGO_GOSTRING_TYPEDEF
56
+ typedef _GoString_ GoString;
57
+ #endif
58
+ typedef void *GoMap;
59
+ typedef void *GoChan;
60
+ typedef struct { void *t; void *v; } GoInterface;
61
+ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
62
+
63
+ #endif
64
+
65
+ /* End of boilerplate cgo prologue. */
66
+
67
+ #ifdef __cplusplus
68
+ extern "C" {
69
+ #endif
70
+
71
+
72
+ extern char* fingerprint(char* p0);
73
+
74
+ #ifdef __cplusplus
75
+ }
76
+ #endif
Binary file
data/go/go.mod ADDED
@@ -0,0 +1,5 @@
1
+ module github.com/nayuta-yanagisawa/nt-fingerprint/go
2
+
3
+ go 1.15
4
+
5
+ require github.com/percona/go-mysql v0.0.0-20200511222729-cd2547baca36
data/go/go.sum ADDED
@@ -0,0 +1,2 @@
1
+ github.com/percona/go-mysql v0.0.0-20200511222729-cd2547baca36 h1:j1o9HyH+5QLfKONVNRp6LCSYBJnIVKzSGrzTsrWXxsQ=
2
+ github.com/percona/go-mysql v0.0.0-20200511222729-cd2547baca36/go.mod h1:/SGLf9OMxlnK6jq4mkFiImBcJXXk5jwD+lDrwDaGXcw=
data/go/libfp.go ADDED
@@ -0,0 +1,14 @@
1
+ package main
2
+
3
+ import (
4
+ "C"
5
+
6
+ "github.com/percona/go-mysql/query"
7
+ )
8
+
9
+ //export fingerprint
10
+ func fingerprint(q *C.char) *C.char {
11
+ return C.CString(query.Fingerprint(C.GoString(q)))
12
+ }
13
+
14
+ func main() {}
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'fingerprint/version'
4
+ require_relative 'fingerprint/fingerprint'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Nt
6
+ # Fingerprint converts queries to fingerprints.
7
+ module Fingerprint
8
+ extend FFI::Library
9
+
10
+ platform = `uname -sm`
11
+
12
+ file = case platform
13
+ when /^Linux.*64/
14
+ 'libfp-linux-amd64.so'
15
+ when /^Darwin.*64/
16
+ 'libfp-darwin-10.6-amd64.dylib'
17
+ else
18
+ abort 'nt-fingerprint does not support your platform.'
19
+ end
20
+
21
+ ffi_lib File.expand_path("../../../go/build/#{file}", __dir__)
22
+ attach_function :fingerprint, [:string], :string
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nt
4
+ module Fingerprint
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/nt/fingerprint/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'nt-fingerprint'
7
+ spec.version = Nt::Fingerprint::VERSION
8
+ spec.authors = ['Nayuta Yanagisawa']
9
+ spec.email = ['nayuta.yanagisawa@hey.com']
10
+
11
+ spec.summary = 'nt-fingerprint convert queries into fingerprints.'
12
+ spec.description = spec.summary
13
+ spec.homepage = 'https://github.com/nayuta-yanagisawa/nt-fingerprint'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = spec.homepage
18
+ spec.metadata['changelog_uri'] = spec.homepage
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'ffi'
30
+ spec.add_development_dependency 'rspec'
31
+ spec.add_development_dependency 'rubocop'
32
+ spec.add_development_dependency 'rake'
33
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nt-fingerprint
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nayuta Yanagisawa
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: nt-fingerprint convert queries into fingerprints.
70
+ email:
71
+ - nayuta.yanagisawa@hey.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".github/workflows/test.yml"
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".rubocop.yml"
80
+ - ".rubocop_todo.yml"
81
+ - CHANGELOG.md
82
+ - Gemfile
83
+ - LICENSE
84
+ - Makefile
85
+ - README.md
86
+ - Rakefile
87
+ - go/build/libfp-darwin-10.6-amd64.dylib
88
+ - go/build/libfp-darwin-10.6-amd64.h
89
+ - go/build/libfp-linux-amd64.h
90
+ - go/build/libfp-linux-amd64.so
91
+ - go/go.mod
92
+ - go/go.sum
93
+ - go/libfp.go
94
+ - lib/nt/fingerprint.rb
95
+ - lib/nt/fingerprint/fingerprint.rb
96
+ - lib/nt/fingerprint/version.rb
97
+ - nt-fingerprint.gemspec
98
+ homepage: https://github.com/nayuta-yanagisawa/nt-fingerprint
99
+ licenses: []
100
+ metadata:
101
+ homepage_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
102
+ source_code_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
103
+ changelog_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 2.5.0
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubygems_version: 3.1.4
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: nt-fingerprint convert queries into fingerprints.
123
+ test_files: []