database_cleaner-spanner 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +3 -0
  3. data/CHANGELOG.md +4 -2
  4. data/LICENSE +21 -0
  5. data/README.md +6 -0
  6. data/database_cleaner-spanner.gemspec +3 -0
  7. data/example/rails/.gitattributes +7 -0
  8. data/example/rails/.gitignore +39 -0
  9. data/example/rails/.rspec +1 -0
  10. data/example/rails/.ruby-version +1 -0
  11. data/example/rails/Gemfile +69 -0
  12. data/example/rails/README.md +24 -0
  13. data/example/rails/Rakefile +6 -0
  14. data/example/rails/app/assets/config/manifest.js +4 -0
  15. data/example/rails/app/assets/images/.keep +0 -0
  16. data/example/rails/app/assets/stylesheets/application.css +15 -0
  17. data/example/rails/app/channels/application_cable/channel.rb +4 -0
  18. data/example/rails/app/channels/application_cable/connection.rb +4 -0
  19. data/example/rails/app/controllers/application_controller.rb +2 -0
  20. data/example/rails/app/controllers/concerns/.keep +0 -0
  21. data/example/rails/app/helpers/application_helper.rb +2 -0
  22. data/example/rails/app/javascript/application.js +3 -0
  23. data/example/rails/app/javascript/controllers/application.js +9 -0
  24. data/example/rails/app/javascript/controllers/hello_controller.js +7 -0
  25. data/example/rails/app/javascript/controllers/index.js +11 -0
  26. data/example/rails/app/jobs/application_job.rb +7 -0
  27. data/example/rails/app/mailers/application_mailer.rb +4 -0
  28. data/example/rails/app/models/album.rb +5 -0
  29. data/example/rails/app/models/application_record.rb +5 -0
  30. data/example/rails/app/models/concerns/.keep +0 -0
  31. data/example/rails/app/models/customer.rb +3 -0
  32. data/example/rails/app/models/order.rb +4 -0
  33. data/example/rails/app/models/product.rb +3 -0
  34. data/example/rails/app/models/singer.rb +4 -0
  35. data/example/rails/app/models/song.rb +15 -0
  36. data/example/rails/app/views/layouts/application.html.erb +16 -0
  37. data/example/rails/app/views/layouts/mailer.html.erb +13 -0
  38. data/example/rails/app/views/layouts/mailer.text.erb +1 -0
  39. data/example/rails/bin/bundle +114 -0
  40. data/example/rails/bin/importmap +4 -0
  41. data/example/rails/bin/rails +4 -0
  42. data/example/rails/bin/rake +4 -0
  43. data/example/rails/bin/setup +33 -0
  44. data/example/rails/config/application.rb +37 -0
  45. data/example/rails/config/boot.rb +4 -0
  46. data/example/rails/config/cable.yml +10 -0
  47. data/example/rails/config/credentials.yml.enc +1 -0
  48. data/example/rails/config/database.yml +18 -0
  49. data/example/rails/config/environment.rb +5 -0
  50. data/example/rails/config/environments/development.rb +70 -0
  51. data/example/rails/config/environments/production.rb +93 -0
  52. data/example/rails/config/environments/test.rb +60 -0
  53. data/example/rails/config/importmap.rb +7 -0
  54. data/example/rails/config/initializers/assets.rb +12 -0
  55. data/example/rails/config/initializers/content_security_policy.rb +25 -0
  56. data/example/rails/config/initializers/filter_parameter_logging.rb +8 -0
  57. data/example/rails/config/initializers/inflections.rb +16 -0
  58. data/example/rails/config/initializers/permissions_policy.rb +11 -0
  59. data/example/rails/config/locales/en.yml +33 -0
  60. data/example/rails/config/puma.rb +43 -0
  61. data/example/rails/config/routes.rb +6 -0
  62. data/example/rails/config/storage.yml +34 -0
  63. data/example/rails/config.ru +6 -0
  64. data/example/rails/db/migrate/20221113100815_create_customers.rb +9 -0
  65. data/example/rails/db/migrate/20221113101016_create_products.rb +10 -0
  66. data/example/rails/db/migrate/20221113101027_create_orders.rb +11 -0
  67. data/example/rails/db/migrate/20221113101034_create_singers.rb +10 -0
  68. data/example/rails/db/migrate/20221113101039_create_albums.rb +12 -0
  69. data/example/rails/db/migrate/20221113101044_create_songs.rb +13 -0
  70. data/example/rails/db/schema.rb +58 -0
  71. data/example/rails/db/seeds.rb +7 -0
  72. data/example/rails/lib/assets/.keep +0 -0
  73. data/example/rails/lib/tasks/.keep +0 -0
  74. data/example/rails/log/.keep +0 -0
  75. data/example/rails/public/404.html +67 -0
  76. data/example/rails/public/422.html +67 -0
  77. data/example/rails/public/500.html +66 -0
  78. data/example/rails/public/apple-touch-icon-precomposed.png +0 -0
  79. data/example/rails/public/apple-touch-icon.png +0 -0
  80. data/example/rails/public/favicon.ico +0 -0
  81. data/example/rails/public/robots.txt +1 -0
  82. data/example/rails/spec/factories/factory.rb +33 -0
  83. data/example/rails/spec/models/album_spec.rb +5 -0
  84. data/example/rails/spec/models/customer_spec.rb +5 -0
  85. data/example/rails/spec/models/order_spec.rb +5 -0
  86. data/example/rails/spec/models/product_spec.rb +5 -0
  87. data/example/rails/spec/models/singer_spec.rb +5 -0
  88. data/example/rails/spec/models/song_spec.rb +5 -0
  89. data/example/rails/spec/rails_helper.rb +70 -0
  90. data/example/rails/spec/sample_spec.rb +14 -0
  91. data/example/rails/spec/spec_helper.rb +94 -0
  92. data/example/rails/spec/support/factory_bot.rb +3 -0
  93. data/example/rails/storage/.keep +0 -0
  94. data/example/rails/tmp/.keep +0 -0
  95. data/example/rails/tmp/pids/.keep +0 -0
  96. data/example/rails/tmp/storage/.keep +0 -0
  97. data/example/rails/vendor/.keep +0 -0
  98. data/example/rails/vendor/javascript/.keep +0 -0
  99. data/lib/database_cleaner/spanner/deletion.rb +31 -5
  100. data/lib/database_cleaner/spanner/version.rb +1 -1
  101. data/scripts/performance_test.rb +127 -0
  102. data/scripts/schema.sql +93 -0
  103. metadata +125 -2
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ raise "emulator is enabled" if ENV["SPANNER_EMULATOR_HOST"]
4
+
5
+ require "base64"
6
+ require "benchmark"
7
+
8
+ require_relative "../spec/spanner_admin"
9
+ require_relative "../lib/database_cleaner/spanner/deletion"
10
+
11
+ class BenchmarkRunner
12
+ def initialize(n = 1)
13
+ @n = n
14
+ end
15
+
16
+ def run
17
+ puts "Creating instance..."
18
+ admin.create_instance
19
+ puts "Creating database..."
20
+ admin.create_database
21
+ puts
22
+
23
+ Benchmark.bm(20) do |x|
24
+ run_test(x, :test_batch_update)
25
+ run_test(x, :test_delete_each)
26
+ end
27
+ ensure
28
+ puts
29
+ puts "Dropping database..."
30
+ admin.drop_database
31
+ end
32
+
33
+ private
34
+
35
+ def test_batch_update
36
+ cleaner = DatabaseCleaner::Spanner::Deletion.new(batch_deletion: true)
37
+ cleaner.db = db
38
+ cleaner.clean
39
+ end
40
+
41
+ def test_delete_each
42
+ cleaner = DatabaseCleaner::Spanner::Deletion.new(batch_deletion: false)
43
+ cleaner.db = db
44
+ cleaner.clean
45
+ end
46
+
47
+ def run_test(x, test_name)
48
+ preprocess
49
+ x.report(test_name) do
50
+ @n.times do
51
+ send(test_name)
52
+ end
53
+ end
54
+ ensure
55
+ postprocess
56
+ end
57
+
58
+ def preprocess
59
+ client.insert("Users", [{UserId: "user1"}, {UserId: "user2"}])
60
+ client.insert("Followings", [{FolloweeId: "user1", FollowerId: "user2"}])
61
+ client.insert("Posts", [{PostId: "post1", UserId: "user1", Text: "text"}])
62
+ client.insert("Bookmarks", [{UserId: "user2", PostId: "post1"}])
63
+ client.insert("Images", [{PostId: "post1", ImageId: "image1", Image: Base64.encode64("")}])
64
+ client.insert("Replies", [{PostId: "post1", ReplyId: "reply1", UserId: "user2", Text: "text"}])
65
+ client.insert("Likes", [{PostId: "post1", LikerId: "user2"}])
66
+ client.insert("ChatRooms", [{ChatRoomId: "chatRoom1", ChatRoomName: "name"}])
67
+ client.insert("ChatRoomMembers", [{ChatRoomId: "chatRoom1", UserId: "user1"}])
68
+ client.insert("ChatRoomMessages", [{ChatRoomId: "chatRoom1", ChatRoomMessageId: "chatRoomMessage1", UserId: "user1", Text: "text"}])
69
+ client.insert("Communities", [{CommunityId: "community1", CommunityName: "name", OwnerId: "user1"}])
70
+ client.insert("CommunityBelongings", [{UserId: "user1", CommunityId: "community1"}])
71
+ client.insert("CommunityPosts", [{CommunityId: "community1", PostId: "post1"}])
72
+ end
73
+
74
+ def postprocess
75
+ %w[
76
+ Users Followings Posts Bookmarks Images Replies Likes
77
+ ChatRooms ChatRoomMembers ChatRoomMessages
78
+ Communities CommunityBelongings CommunityPosts
79
+ ].each do |table|
80
+ count = count_rows(table)
81
+ if count != 0
82
+ raise "#{table} was not cleaned up"
83
+ end
84
+ end
85
+ end
86
+
87
+ def count_rows(table)
88
+ result = client.execute_query("SELECT COUNT(1) FROM #{table}")
89
+ result.rows.first[0]
90
+ end
91
+
92
+ def admin
93
+ @admin ||= SpannerAdmin.new(
94
+ project_id: project_id,
95
+ instance_id: instance_id,
96
+ database_id: database_id,
97
+ schema_file: File.expand_path("./schema.sql", __dir__)
98
+ )
99
+ end
100
+
101
+ def client
102
+ @client ||= Google::Cloud::Spanner.new(project_id: project_id)
103
+ .client(instance_id, database_id)
104
+ end
105
+
106
+ def project_id
107
+ @project_id ||= SpannerAdmin.get_project_id
108
+ end
109
+
110
+ def instance_id
111
+ @instance_id ||= ENV.fetch("SPANNER_INSTANCE_ID")
112
+ end
113
+
114
+ def database_id
115
+ @database_id ||= "performance-#{Time.now.to_i}"
116
+ end
117
+
118
+ def db
119
+ @db ||= {
120
+ project_id: project_id,
121
+ instance_id: instance_id,
122
+ database_id: database_id
123
+ }
124
+ end
125
+ end
126
+
127
+ BenchmarkRunner.new(100).run
@@ -0,0 +1,93 @@
1
+ CREATE TABLE Users (
2
+ UserId STRING(36) NOT NULL,
3
+ ) PRIMARY KEY (UserId);
4
+
5
+ CREATE TABLE Followings (
6
+ FolloweeId STRING(36) NOT NULL,
7
+ FollowerId STRING(36) NOT NULL,
8
+
9
+ FOREIGN KEY (FolloweeId) REFERENCES Users (UserId),
10
+ FOREIGN KEY (FollowerId) REFERENCES Users (UserId),
11
+ ) PRIMARY KEY (FolloweeId, FollowerId);
12
+
13
+ CREATE TABLE Posts (
14
+ PostId STRING(36) NOT NULL,
15
+ UserId STRING(36) NOT NULL,
16
+ Text STRING(MAX) NOT NULL,
17
+
18
+ FOREIGN KEY (UserId) REFERENCES Users (UserId),
19
+ ) PRIMARY KEY (PostId);
20
+
21
+ CREATE TABLE Bookmarks (
22
+ UserId STRING(36) NOT NULL,
23
+ PostId STRING(36) NOT NULL,
24
+
25
+ FOREIGN KEY (PostId) REFERENCES Posts (PostId),
26
+ ) PRIMARY KEY (UserId, PostId), INTERLEAVE IN PARENT Users;
27
+
28
+ CREATE TABLE Images (
29
+ PostId STRING(36) NOT NULL,
30
+ ImageId STRING(36) NOT NULL,
31
+ Image BYTES(1024) NOT NULL,
32
+ ) PRIMARY KEY (PostId, ImageId), INTERLEAVE IN PARENT Posts;
33
+
34
+ CREATE TABLE Replies (
35
+ PostId STRING(36) NOT NULL,
36
+ ReplyId STRING(36) NOT NULL,
37
+ UserId STRING(36) NOT NULL,
38
+ Text STRING(MAX) NOT NULL,
39
+
40
+ FOREIGN KEY (UserId) REFERENCES Users (UserId),
41
+ ) PRIMARY KEY (PostId, ReplyId), INTERLEAVE IN PARENT Posts;
42
+
43
+ CREATE TABLE Likes (
44
+ PostId STRING(36) NOT NULL,
45
+ LikerId STRING(36) NOT NULL,
46
+
47
+ FOREIGN KEY (LikerId) REFERENCES Users (UserId),
48
+ ) PRIMARY KEY (PostId, LikerId), INTERLEAVE IN PARENT Posts;
49
+
50
+ CREATE TABLE ChatRooms (
51
+ ChatRoomId STRING(36) NOT NULL,
52
+ ChatRoomName STRING(128) NOT NULL,
53
+ ) PRIMARY KEY (ChatRoomId);
54
+
55
+ CREATE TABLE ChatRoomMembers (
56
+ ChatRoomId STRING(36) NOT NULL,
57
+ UserId STRING(36) NOT NULL,
58
+
59
+ FOREIGN KEY (ChatRoomId) REFERENCES ChatRooms (ChatRoomId),
60
+ FOREIGN KEY (UserId) REFERENCES Users (UserId),
61
+ ) PRIMARY KEY (ChatRoomId, UserId);
62
+
63
+ CREATE TABLE ChatRoomMessages (
64
+ ChatRoomId STRING(36) NOT NULL,
65
+ ChatRoomMessageId STRING(36) NOT NULL,
66
+ UserId STRING(36) NOT NULL,
67
+ Text STRING(MAX) NOT NULL,
68
+
69
+ FOREIGN KEY (ChatRoomId, UserId) REFERENCES ChatRoomMembers (ChatRoomId, UserId),
70
+ ) PRIMARY KEY (ChatRoomId, ChatRoomMessageId), INTERLEAVE IN PARENT ChatRooms;
71
+
72
+ CREATE TABLE Communities (
73
+ CommunityId STRING(36) NOT NULL,
74
+ CommunityName STRING(128) NOT NULL,
75
+ OwnerId STRING(36) NOT NULL,
76
+
77
+ FOREIGN KEY (OwnerId) REFERENCES Users (UserId),
78
+ ) PRIMARY KEY (CommunityId);
79
+
80
+ CREATE TABLE CommunityBelongings (
81
+ UserId STRING(36) NOT NULL,
82
+ CommunityId STRING(36) NOT NULL,
83
+
84
+ FOREIGN KEY (CommunityId) REFERENCES Communities (CommunityId),
85
+ ) PRIMARY KEY (UserId, CommunityId), INTERLEAVE IN PARENT Users;
86
+
87
+ CREATE TABLE CommunityPosts (
88
+ CommunityId STRING(36) NOT NULL,
89
+ PostId STRING(36) NOT NULL,
90
+
91
+ FOREIGN KEY (PostId) REFERENCES Posts (PostId),
92
+ ) PRIMARY KEY (CommunityId, PostId), INTERLEAVE IN PARENT Communities;
93
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_cleaner-spanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - nownabe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-13 00:00:00.000000000 Z
11
+ date: 2022-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-spanner
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
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: simplecov-cobertura
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'
41
69
  description: Strategies for cleaning tables on Cloud Spanner. Can be used to ensure
42
70
  a clean state for testing.
43
71
  email:
@@ -51,14 +79,109 @@ files:
51
79
  - CHANGELOG.md
52
80
  - CODE_OF_CONDUCT.md
53
81
  - Gemfile
82
+ - LICENSE
54
83
  - README.md
55
84
  - Rakefile
56
85
  - database_cleaner-spanner.gemspec
86
+ - example/rails/.gitattributes
87
+ - example/rails/.gitignore
88
+ - example/rails/.rspec
89
+ - example/rails/.ruby-version
90
+ - example/rails/Gemfile
91
+ - example/rails/README.md
92
+ - example/rails/Rakefile
93
+ - example/rails/app/assets/config/manifest.js
94
+ - example/rails/app/assets/images/.keep
95
+ - example/rails/app/assets/stylesheets/application.css
96
+ - example/rails/app/channels/application_cable/channel.rb
97
+ - example/rails/app/channels/application_cable/connection.rb
98
+ - example/rails/app/controllers/application_controller.rb
99
+ - example/rails/app/controllers/concerns/.keep
100
+ - example/rails/app/helpers/application_helper.rb
101
+ - example/rails/app/javascript/application.js
102
+ - example/rails/app/javascript/controllers/application.js
103
+ - example/rails/app/javascript/controllers/hello_controller.js
104
+ - example/rails/app/javascript/controllers/index.js
105
+ - example/rails/app/jobs/application_job.rb
106
+ - example/rails/app/mailers/application_mailer.rb
107
+ - example/rails/app/models/album.rb
108
+ - example/rails/app/models/application_record.rb
109
+ - example/rails/app/models/concerns/.keep
110
+ - example/rails/app/models/customer.rb
111
+ - example/rails/app/models/order.rb
112
+ - example/rails/app/models/product.rb
113
+ - example/rails/app/models/singer.rb
114
+ - example/rails/app/models/song.rb
115
+ - example/rails/app/views/layouts/application.html.erb
116
+ - example/rails/app/views/layouts/mailer.html.erb
117
+ - example/rails/app/views/layouts/mailer.text.erb
118
+ - example/rails/bin/bundle
119
+ - example/rails/bin/importmap
120
+ - example/rails/bin/rails
121
+ - example/rails/bin/rake
122
+ - example/rails/bin/setup
123
+ - example/rails/config.ru
124
+ - example/rails/config/application.rb
125
+ - example/rails/config/boot.rb
126
+ - example/rails/config/cable.yml
127
+ - example/rails/config/credentials.yml.enc
128
+ - example/rails/config/database.yml
129
+ - example/rails/config/environment.rb
130
+ - example/rails/config/environments/development.rb
131
+ - example/rails/config/environments/production.rb
132
+ - example/rails/config/environments/test.rb
133
+ - example/rails/config/importmap.rb
134
+ - example/rails/config/initializers/assets.rb
135
+ - example/rails/config/initializers/content_security_policy.rb
136
+ - example/rails/config/initializers/filter_parameter_logging.rb
137
+ - example/rails/config/initializers/inflections.rb
138
+ - example/rails/config/initializers/permissions_policy.rb
139
+ - example/rails/config/locales/en.yml
140
+ - example/rails/config/puma.rb
141
+ - example/rails/config/routes.rb
142
+ - example/rails/config/storage.yml
143
+ - example/rails/db/migrate/20221113100815_create_customers.rb
144
+ - example/rails/db/migrate/20221113101016_create_products.rb
145
+ - example/rails/db/migrate/20221113101027_create_orders.rb
146
+ - example/rails/db/migrate/20221113101034_create_singers.rb
147
+ - example/rails/db/migrate/20221113101039_create_albums.rb
148
+ - example/rails/db/migrate/20221113101044_create_songs.rb
149
+ - example/rails/db/schema.rb
150
+ - example/rails/db/seeds.rb
151
+ - example/rails/lib/assets/.keep
152
+ - example/rails/lib/tasks/.keep
153
+ - example/rails/log/.keep
154
+ - example/rails/public/404.html
155
+ - example/rails/public/422.html
156
+ - example/rails/public/500.html
157
+ - example/rails/public/apple-touch-icon-precomposed.png
158
+ - example/rails/public/apple-touch-icon.png
159
+ - example/rails/public/favicon.ico
160
+ - example/rails/public/robots.txt
161
+ - example/rails/spec/factories/factory.rb
162
+ - example/rails/spec/models/album_spec.rb
163
+ - example/rails/spec/models/customer_spec.rb
164
+ - example/rails/spec/models/order_spec.rb
165
+ - example/rails/spec/models/product_spec.rb
166
+ - example/rails/spec/models/singer_spec.rb
167
+ - example/rails/spec/models/song_spec.rb
168
+ - example/rails/spec/rails_helper.rb
169
+ - example/rails/spec/sample_spec.rb
170
+ - example/rails/spec/spec_helper.rb
171
+ - example/rails/spec/support/factory_bot.rb
172
+ - example/rails/storage/.keep
173
+ - example/rails/tmp/.keep
174
+ - example/rails/tmp/pids/.keep
175
+ - example/rails/tmp/storage/.keep
176
+ - example/rails/vendor/.keep
177
+ - example/rails/vendor/javascript/.keep
57
178
  - lib/database_cleaner-spanner.rb
58
179
  - lib/database_cleaner/spanner.rb
59
180
  - lib/database_cleaner/spanner/deletion.rb
60
181
  - lib/database_cleaner/spanner/table_dependency.rb
61
182
  - lib/database_cleaner/spanner/version.rb
183
+ - scripts/performance_test.rb
184
+ - scripts/schema.sql
62
185
  - sig/database_cleaner/spanner.rbs
63
186
  homepage: https://github.com/nownabe/database_cleaner-spanner
64
187
  licenses: