database_cleaner-spanner 0.1.0 → 0.1.1

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.
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: