mysql_rewinder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 312985891d45112d6c806ae4bdd2f2b741f1150bdfe6e5884e4cc0f327ebfbcf
4
+ data.tar.gz: 853345a9fba1a84b22b3f051ff1cc30f7495153ac2eb47fd559c72bf9c677ce7
5
+ SHA512:
6
+ metadata.gz: 8afda05e048b531c39b89dc9136e5d7e32407c01c5c672433e30a10498bdf8820fa0fa08a581b22ecf25afe0ebcf11ae6a8590977af3e4418790f7abe54837b3
7
+ data.tar.gz: ae8539d8a9e068f2a451794ff967efaf86d93b5d09450172fbe4b03b09d5e2bdd6b04b82b38f043c9ce1f8e7cd3d587e405fcd30b112a661489bbe3255123883
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in mysql_rewinder.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "steep"
11
+ gem "trilogy"
12
+ gem "mysql2"
data/Gemfile.lock ADDED
@@ -0,0 +1,102 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mysql_rewinder (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (7.1.1)
10
+ base64
11
+ bigdecimal
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ connection_pool (>= 2.2.5)
14
+ drb
15
+ i18n (>= 1.6, < 2)
16
+ minitest (>= 5.1)
17
+ mutex_m
18
+ tzinfo (~> 2.0)
19
+ ast (2.4.2)
20
+ base64 (0.2.0)
21
+ bigdecimal (3.1.4)
22
+ concurrent-ruby (1.2.2)
23
+ connection_pool (2.4.1)
24
+ csv (3.2.7)
25
+ diff-lcs (1.5.0)
26
+ drb (2.2.0)
27
+ ruby2_keywords
28
+ ffi (1.16.3)
29
+ fileutils (1.7.2)
30
+ i18n (1.14.1)
31
+ concurrent-ruby (~> 1.0)
32
+ json (2.6.3)
33
+ language_server-protocol (3.17.0.3)
34
+ listen (3.8.0)
35
+ rb-fsevent (~> 0.10, >= 0.10.3)
36
+ rb-inotify (~> 0.9, >= 0.9.10)
37
+ logger (1.6.0)
38
+ minitest (5.20.0)
39
+ mutex_m (0.2.0)
40
+ mysql2 (0.5.5)
41
+ parser (3.2.2.4)
42
+ ast (~> 2.4.1)
43
+ racc
44
+ racc (1.7.3)
45
+ rainbow (3.1.1)
46
+ rake (13.1.0)
47
+ rb-fsevent (0.11.2)
48
+ rb-inotify (0.10.1)
49
+ ffi (~> 1.0)
50
+ rbs (3.2.2)
51
+ rspec (3.12.0)
52
+ rspec-core (~> 3.12.0)
53
+ rspec-expectations (~> 3.12.0)
54
+ rspec-mocks (~> 3.12.0)
55
+ rspec-core (3.12.2)
56
+ rspec-support (~> 3.12.0)
57
+ rspec-expectations (3.12.3)
58
+ diff-lcs (>= 1.2.0, < 2.0)
59
+ rspec-support (~> 3.12.0)
60
+ rspec-mocks (3.12.6)
61
+ diff-lcs (>= 1.2.0, < 2.0)
62
+ rspec-support (~> 3.12.0)
63
+ rspec-support (3.12.1)
64
+ ruby2_keywords (0.0.5)
65
+ securerandom (0.3.0)
66
+ steep (1.5.3)
67
+ activesupport (>= 5.1)
68
+ concurrent-ruby (>= 1.1.10)
69
+ csv (>= 3.0.9)
70
+ fileutils (>= 1.1.0)
71
+ json (>= 2.1.0)
72
+ language_server-protocol (>= 3.15, < 4.0)
73
+ listen (~> 3.0)
74
+ logger (>= 1.3.0)
75
+ parser (>= 3.1)
76
+ rainbow (>= 2.2.2, < 4.0)
77
+ rbs (>= 3.1.0)
78
+ securerandom (>= 0.1)
79
+ strscan (>= 1.0.0)
80
+ terminal-table (>= 2, < 4)
81
+ strscan (3.0.7)
82
+ terminal-table (3.0.2)
83
+ unicode-display_width (>= 1.1.1, < 3)
84
+ trilogy (2.6.0)
85
+ tzinfo (2.0.6)
86
+ concurrent-ruby (~> 1.0)
87
+ unicode-display_width (2.5.0)
88
+
89
+ PLATFORMS
90
+ arm64-darwin
91
+ x86_64-linux
92
+
93
+ DEPENDENCIES
94
+ mysql2
95
+ mysql_rewinder!
96
+ rake (~> 13.0)
97
+ rspec (~> 3.0)
98
+ steep
99
+ trilogy
100
+
101
+ BUNDLED WITH
102
+ 2.3.15
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Yusuke Sangenya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # MysqlRewinder
2
+
3
+ MysqlRewinder is a simple, stable, and fast database cleaner for mysql.
4
+
5
+ ## Features
6
+
7
+ * Fast cleanup using `DELETE` query
8
+ * Supports multi-database
9
+ * Supports both `mysql2` and `trilogy` as a client library
10
+ * Works without ActiveRecord
11
+ * Works with `fork`
12
+
13
+ ## How does it work?
14
+
15
+ 1. Capture SQL statements during test execution and extract `INSERT`ed table names, and record them into temporary files
16
+ 2. Aggregate tmp files and execute DELETE query for `INSERT`ed tables
17
+
18
+ ## What does `stable` mean?
19
+
20
+ MysqlRewinder is stable because it does not depend on ActiveRecord's internal implementation.
21
+ It only depends on `Mysql2::Client#query` and `Trilogy#query`.
22
+
23
+ ## Installation
24
+
25
+ Add this line to your Gemfile's `:test` group:
26
+
27
+ ```ruby
28
+ gem 'trilogy'
29
+ # gem 'mysql2' # described later
30
+ gem 'mysql_rewinder'
31
+ ```
32
+
33
+ And then execute:
34
+
35
+ ```shell
36
+ $ bundle
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Basic configuration
42
+
43
+ ```ruby
44
+ RSpec.configure do |config|
45
+ config.before(:suite) do
46
+ db_config = {
47
+ host: '127.0.0.1',
48
+ port: '3306',
49
+ username: 'user1',
50
+ password: 'my_secure_password',
51
+ database: 'myapp-test'
52
+ }
53
+ MysqlRewinder.setup([db_config])
54
+ MysqlRewinder.clean_all
55
+ end
56
+
57
+ config.after(:each) do
58
+ MysqlRewinder.clean
59
+ end
60
+ end
61
+ ```
62
+
63
+ ### Multi-database
64
+
65
+ Pass all configurations to `MysqlRewinder.setup`.
66
+
67
+ ```ruby
68
+ MysqlRewinder.setup(
69
+ [
70
+ { host: '127.0.0.1', port: '3306', username: 'user1', password: 'my_secure_password', database: 'myapp-test-shard1' },
71
+ { host: '127.0.0.1', port: '3306', username: 'user1', password: 'my_secure_password', database: 'myapp-test-shard2' },
72
+ ]
73
+ )
74
+ ```
75
+
76
+ ### mysql2
77
+
78
+ If you want to use `mysql2` as a client library, do the following:
79
+
80
+ * Write `gem 'mysql2'` in your `Gemfile`
81
+ * Pass `adapter: :mysql2` to `MysqlRewinder.setup`.
82
+
83
+ ```ruby
84
+ MysqlRewinder.setup(db_configs, adapter: :mysql2)
85
+ ```
86
+
87
+ ### ActiveRecord
88
+
89
+ If you want to use MysqlRewinder with ActiveRecord, do the following:
90
+
91
+ * Generate db_configs from `ActiveRecord::Base.configurations`
92
+ * Pass `ActiveRecord::SchemaMigration.new(nil).table_name` and `ActiveRecord::Base.internal_metadata_table_name` to `DatabaseRewinder.setup` as `except_tables`
93
+
94
+ ```ruby
95
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: 'test').map(&:configuration_hash)
96
+ except_tables = [
97
+ ActiveRecord::Base.internal_metadata_table_name,
98
+
99
+ # for AR >= 7.1
100
+ ActiveRecord::SchemaMigration.new(nil).table_name,
101
+ # for AR < 7.1
102
+ # ActiveRecord::SchemaMigration.table_name,
103
+ ]
104
+
105
+ MysqlRewinder.setup(db_configs, except_tables: except_tables)
106
+ ```
107
+
108
+ ## License
109
+
110
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
111
+
112
+ ## Special Thanks
113
+
114
+ * Thank you [@aeroastro](https://github.com/aeroastro) for the idea of using temporary files
115
+ * This gem is heavily inspired by [amatsuda/database_rewinder](https://github.com/amatsuda/database_rewinder).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: %i[spec]
data/Steepfile ADDED
@@ -0,0 +1,20 @@
1
+ D = Steep::Diagnostic
2
+
3
+ target :lib do
4
+ signature "sig"
5
+
6
+ check "lib"
7
+
8
+ library "pathname"
9
+ library "fileutils"
10
+ library "tmpdir"
11
+ library "forwardable"
12
+
13
+ configure_code_diagnostics(D::Ruby.lenient)
14
+ end
15
+
16
+ target :test do
17
+ signature "sig", "sig-private"
18
+
19
+ check "test"
20
+ end
@@ -0,0 +1,32 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class Adapter
4
+ def self.generate(adapter, config)
5
+ case adapter
6
+ when :trilogy
7
+ require 'trilogy'
8
+ require_relative '../ext/trilogy'
9
+
10
+ TrilogyAdapter.new(config)
11
+ when :mysql2
12
+ require 'mysql2'
13
+ require_relative '../ext/mysql2_client'
14
+
15
+ Mysql2Adapter.new(config)
16
+ else
17
+ raise 'adapter must be either :trilogy or :mysql2'
18
+ end
19
+ end
20
+
21
+ def initialize(_config); end
22
+
23
+ def query(sql)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def execute(sql)
28
+ raise NotImplementedError
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class Mysql2Adapter < Adapter
4
+ def initialize(db_config)
5
+ super
6
+ @db_config = db_config
7
+ connect
8
+ end
9
+
10
+ def query(sql)
11
+ with_reconnect do
12
+ @client.query(sql, as: :array).to_a
13
+ end
14
+ end
15
+
16
+ def execute(sql)
17
+ with_reconnect do
18
+ @client.query(sql)
19
+ @client.store_result while @client.next_result
20
+ end
21
+ end
22
+
23
+ private
24
+ def with_reconnect(&block)
25
+ retry_count = 0
26
+ begin
27
+ block.call
28
+ rescue Mysql2::Error => e
29
+ raise e if retry_count > 3
30
+
31
+ connect
32
+ retry_count += 1
33
+
34
+ retry
35
+ end
36
+ end
37
+
38
+ def connect
39
+ @client&.close
40
+ @client = Mysql2::Client.new(@db_config.merge(connect_flags: Mysql2::Client::MULTI_STATEMENTS))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class TrilogyAdapter < Adapter
4
+ def initialize(db_config)
5
+ super
6
+ @db_config = db_config
7
+ connect
8
+ end
9
+
10
+ def query(sql)
11
+ with_reconnect do
12
+ @client.query(sql).to_a
13
+ end
14
+ end
15
+
16
+ def execute(sql)
17
+ with_reconnect do
18
+ @client.query(sql)
19
+ @client.next_result while @client.more_results_exist?
20
+ end
21
+ end
22
+
23
+ private
24
+ def with_reconnect(&block)
25
+ retry_count = 0
26
+ begin
27
+ block.call
28
+ rescue Trilogy::Error => e
29
+ raise e if retry_count > 3
30
+
31
+ connect
32
+ retry_count += 1
33
+
34
+ retry
35
+ end
36
+ end
37
+
38
+ def connect
39
+ @client&.close
40
+ @client = Trilogy.new(@db_config.merge(multi_statement: true))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'cleaner/adapter'
2
+ require_relative 'cleaner/mysql2_adapter'
3
+ require_relative 'cleaner/trilogy_adapter'
4
+
5
+ class MysqlRewinder
6
+ class Cleaner
7
+ attr_reader :db_config
8
+
9
+ def initialize(db_config, except_tables:, adapter:)
10
+ @db_config = db_config
11
+ @client = Adapter.generate(adapter, db_config.transform_keys(&:to_sym))
12
+ @except_tables = except_tables
13
+ end
14
+
15
+ def clean_all
16
+ clean(tables: all_tables)
17
+ end
18
+
19
+ def clean(tables:)
20
+ target_tables = (tables - @except_tables) & all_tables
21
+ return if target_tables.empty?
22
+
23
+ @client.execute(target_tables.map { |table| "DELETE FROM #{table}" }.join(';'))
24
+ end
25
+
26
+ def all_tables
27
+ @all_tables ||= @client.query(<<~SQL).flatten
28
+ SELECT TABLE_NAME
29
+ FROM INFORMATION_SCHEMA.TABLES
30
+ WHERE TABLE_SCHEMA = DATABASE()
31
+ SQL
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ require 'mysql2'
2
+
3
+ class MysqlRewinder
4
+ module Ext
5
+ module Mysql2Client
6
+ def query(sql, _options = {})
7
+ MysqlRewinder.record_inserted_table(sql)
8
+
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ ::Mysql2::Client.prepend ::MysqlRewinder::Ext::Mysql2Client
@@ -0,0 +1,14 @@
1
+ require 'trilogy'
2
+
3
+ class MysqlRewinder
4
+ module Ext
5
+ module Trilogy
6
+ def query(sql)
7
+ MysqlRewinder.record_inserted_table(sql)
8
+
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ ::Trilogy.prepend ::MysqlRewinder::Ext::Trilogy
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MysqlRewinder
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "mysql_rewinder/version"
4
+ require_relative "mysql_rewinder/cleaner"
5
+ require 'set'
6
+ require 'tmpdir'
7
+ require 'fileutils'
8
+ require 'forwardable'
9
+
10
+ class MysqlRewinder
11
+ class << self
12
+ extend Forwardable
13
+ delegate %i[clean clean_all record_inserted_table] => :@instance
14
+
15
+ def setup(db_configs, except_tables: [], adapter: :trilogy)
16
+ @instance = new(db_configs: db_configs, except_tables: except_tables, adapter: adapter)
17
+ end
18
+ end
19
+
20
+ def initialize(db_configs:, except_tables:, adapter:)
21
+ @initialized_pid = Process.pid
22
+ @inserted_table_record_dir = Pathname(Dir.tmpdir)
23
+ @cleaners = db_configs.map do |db_config|
24
+ Cleaner.new(
25
+ db_config.transform_keys(&:to_sym),
26
+ except_tables: except_tables,
27
+ adapter: adapter
28
+ )
29
+ end
30
+ reset_inserted_tables
31
+ end
32
+
33
+ def record_inserted_table(sql)
34
+ return unless @initialized_pid
35
+
36
+ @inserted_tables ||= Set.new
37
+ sql.split(';').each do |statement|
38
+ match = statement.match(/\A\s*INSERT(?:\s+IGNORE)?(?:\s+INTO)?\s+(?:\.*[`"]?([^.\s`"(]+)[`"]?)*/i)
39
+ next unless match
40
+
41
+ table = match[1]
42
+ @inserted_tables << table if table
43
+ end
44
+ File.write(
45
+ @inserted_table_record_dir.join("#{@initialized_pid}.#{Process.pid}.inserted_tables").to_s,
46
+ @inserted_tables.to_a.join(',')
47
+ )
48
+ end
49
+
50
+ def reset_inserted_tables
51
+ unless @initialized_pid == Process.pid
52
+ raise "MysqlRewinder is initialize in process #{@initialized_pid}, but reset_inserted_tables is called in process #{Process.pid}"
53
+ end
54
+
55
+ @inserted_tables = Set.new
56
+ FileUtils.rm(Dir.glob(@inserted_table_record_dir.join("#{@initialized_pid}.*.inserted_tables").to_s))
57
+ end
58
+
59
+ def calculate_inserted_tables
60
+ unless @initialized_pid == Process.pid
61
+ raise "MysqlRewinder is initialize in process #{@initialized_pid}, but calculate_inserted_tables is called in process #{Process.pid}"
62
+ end
63
+
64
+ Dir.glob(@inserted_table_record_dir.join("#{@initialized_pid}.*.inserted_tables").to_s).flat_map do |fname|
65
+ File.read(fname).strip.split(',')
66
+ end.uniq
67
+ end
68
+
69
+ def clean_all
70
+ @cleaners.each(&:clean_all)
71
+ reset_inserted_tables
72
+ end
73
+
74
+ def clean
75
+ aggregated_inserted_tables = calculate_inserted_tables
76
+ @cleaners.each { |c| c.clean(tables: aggregated_inserted_tables) }
77
+ reset_inserted_tables
78
+ end
79
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/mysql_rewinder/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "mysql_rewinder"
7
+ spec.version = MysqlRewinder::VERSION
8
+ spec.authors = ["Yusuke Sangenya"]
9
+ spec.email = ["longinus.eva@gmail.com"]
10
+
11
+ spec.summary = "Simple, stable, and fast database cleaner for mysql"
12
+ spec.homepage = "https://github.com/genya0407/mysql_rewinder"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 3.0.0"
15
+
16
+ spec.files = Dir.chdir(__dir__) do
17
+ `git ls-files -z`.split("\x0").reject do |f|
18
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
19
+ end
20
+ end
21
+ spec.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,10 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class Adapter
4
+ def self.generate: (Symbol adapter, Hash[Symbol,String] db_config) -> Adapter
5
+ def initialize: (Hash[Symbol,String] db_config) -> untyped
6
+ def query: (String sql) -> Array[Array[Object]]
7
+ def execute: (String sql) -> void
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class Mysql2Adapter < Adapter
4
+ @db_config: Hash[Symbol,String]
5
+ @client: Mysql2::Client
6
+
7
+ private
8
+
9
+ def with_reconnect: [T] () { () -> T } -> T
10
+ def connect: () -> void
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ class TrilogyAdapter < Adapter
4
+ @db_config: Hash[Symbol,String]
5
+ @client: ::Trilogy
6
+
7
+ private
8
+
9
+ def with_reconnect: [T] () { () -> T } -> T
10
+ def connect: () -> void
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ class MysqlRewinder
2
+ class Cleaner
3
+ @db_config: Hash[Symbol,String]
4
+ @client: Adapter
5
+ @except_tables: Array[String]
6
+ @all_tables: Array[String]
7
+
8
+ attr_reader db_config: Hash[Symbol,String]
9
+
10
+ def initialize: (Hash[Symbol,String] db_config, except_tables: Array[String], adapter: Symbol) -> untyped
11
+ def clean_all: () -> void
12
+ def clean: (tables: untyped) -> void
13
+ def all_tables: () -> void
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ class MysqlRewinder
2
+ module Ext
3
+ module Mysql2Client
4
+ def query: (String sql, ?::Hash[Symbol, Object] _options) -> ::Mysql2::Result
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class MysqlRewinder
2
+ module Ext
3
+ module Trilogy
4
+ def query: (String sql) -> ::Trilogy::Result
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ class Mysql2
2
+ class Result < Enumerator[Array[Object], void]
3
+ end
4
+ class Error < StandardError
5
+ end
6
+
7
+ class Client
8
+ MULTI_STATEMENTS: Integer
9
+
10
+ def initialize: (Hash[Symbol, Object] config) -> untyped
11
+ def close: () -> void
12
+ def next_result: () -> bool
13
+ def store_result: () -> Array[Object]
14
+ def query: (String sql, ?Hash[Symbol, Object] _options) -> Array[Array[Object]]
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ class Trilogy
2
+ class Result < Enumerator[Array[Object], void]
3
+ end
4
+ class Error < StandardError
5
+ end
6
+
7
+ def initialize: (Hash[Symbol,Object] config) -> untyped
8
+ def close: () -> void
9
+ def more_results_exist?: () -> bool
10
+ def next_result: () -> Array[Object]
11
+ def query: (String sql) -> Array[Array[Object]]
12
+ end
@@ -0,0 +1,3 @@
1
+ class MysqlRewinder
2
+ VERSION: String
3
+ end
@@ -0,0 +1,20 @@
1
+ class MysqlRewinder
2
+ self.@instance: MysqlRewinder
3
+ @initialized_pid: Integer
4
+ @inserted_table_record_dir: Object
5
+ # @inserted_table_record_dir: Pathname
6
+ @cleaners: Array[Cleaner]
7
+ @inserted_tables: Set[String]
8
+
9
+ def self.setup: (Array[Hash[Symbol,String]] db_configs, ?except_tables: Array[String], ?adapter: ::Symbol) -> void
10
+ def self.clean_all: () -> void
11
+ def self.clean: () -> void
12
+ def self.record_inserted_table: (String sql) -> void
13
+
14
+ def initialize: (db_configs: Array[Hash[Symbol,String]], except_tables: Array[String], adapter: ::Symbol) -> untyped
15
+ def record_inserted_table: (String sql) -> void
16
+ def reset_inserted_tables: () -> void
17
+ def calculate_inserted_tables: () -> void
18
+ def clean_all: () -> void
19
+ def clean: () -> void
20
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mysql_rewinder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yusuke Sangenya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - longinus.eva@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - Steepfile
27
+ - lib/mysql_rewinder.rb
28
+ - lib/mysql_rewinder/cleaner.rb
29
+ - lib/mysql_rewinder/cleaner/adapter.rb
30
+ - lib/mysql_rewinder/cleaner/mysql2_adapter.rb
31
+ - lib/mysql_rewinder/cleaner/trilogy_adapter.rb
32
+ - lib/mysql_rewinder/ext/mysql2_client.rb
33
+ - lib/mysql_rewinder/ext/trilogy.rb
34
+ - lib/mysql_rewinder/version.rb
35
+ - mysql_rewinder.gemspec
36
+ - sig/mysql_rewinder.rbs
37
+ - sig/mysql_rewinder/cleaner.rbs
38
+ - sig/mysql_rewinder/cleaner/adapter.rbs
39
+ - sig/mysql_rewinder/cleaner/mysql2_adapter.rbs
40
+ - sig/mysql_rewinder/cleaner/trilogy_adapter.rbs
41
+ - sig/mysql_rewinder/ext/mysql2_client.rbs
42
+ - sig/mysql_rewinder/ext/trilogy.rbs
43
+ - sig/mysql_rewinder/mysql2.rbs
44
+ - sig/mysql_rewinder/trilogy.rbs
45
+ - sig/mysql_rewinder/version.rbs
46
+ homepage: https://github.com/genya0407/mysql_rewinder
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 3.0.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.4.10
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Simple, stable, and fast database cleaner for mysql
69
+ test_files: []