dynamo-record 0.2.0 → 0.3.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +15 -0
  3. data/.gitignore +9 -5
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +9 -30
  6. data/.travis.yml +18 -2
  7. data/Dockerfile +22 -0
  8. data/Gemfile +0 -1
  9. data/LICENSE.txt +21 -0
  10. data/README.md +75 -17
  11. data/build.sh +10 -20
  12. data/docker-compose.override.example.yml +19 -0
  13. data/docker-compose.yml +7 -2
  14. data/dynamo-record.gemspec +40 -28
  15. data/lib/dynamo/record.rb +17 -0
  16. data/lib/dynamo/record/marshalers.rb +46 -0
  17. data/lib/dynamo/record/model.rb +127 -0
  18. data/lib/dynamo/record/model_existence_validator.rb +10 -0
  19. data/lib/{dynamo-record → dynamo}/record/railtie.rb +1 -3
  20. data/lib/dynamo/record/table_migration.rb +59 -0
  21. data/lib/dynamo/record/task_helpers/cleanup.rb +21 -0
  22. data/lib/dynamo/record/task_helpers/drop_all_tables.rb +19 -0
  23. data/lib/dynamo/record/task_helpers/drop_table.rb +13 -0
  24. data/lib/dynamo/record/task_helpers/list_tables.rb +15 -0
  25. data/lib/dynamo/record/task_helpers/migration_runner.rb +72 -0
  26. data/lib/dynamo/record/task_helpers/scale.rb +90 -0
  27. data/lib/dynamo/record/version.rb +5 -0
  28. data/lib/tasks/dynamo.rake +7 -7
  29. metadata +96 -37
  30. data/Dockerfile.test +0 -23
  31. data/Gemfile.lock +0 -178
  32. data/doc/testing.md +0 -11
  33. data/docker-compose.dev.override.yml +0 -6
  34. data/lib/dynamo-record.rb +0 -4
  35. data/lib/dynamo-record/marshalers.rb +0 -44
  36. data/lib/dynamo-record/model.rb +0 -127
  37. data/lib/dynamo-record/record.rb +0 -7
  38. data/lib/dynamo-record/record/version.rb +0 -5
  39. data/lib/dynamo-record/table_migration.rb +0 -58
  40. data/lib/dynamo-record/task_helpers/cleanup.rb +0 -19
  41. data/lib/dynamo-record/task_helpers/drop_all_tables.rb +0 -17
  42. data/lib/dynamo-record/task_helpers/drop_table.rb +0 -11
  43. data/lib/dynamo-record/task_helpers/list_tables.rb +0 -13
  44. data/lib/dynamo-record/task_helpers/migration_runner.rb +0 -70
  45. data/lib/dynamo-record/task_helpers/scale.rb +0 -86
  46. data/lib/model_existence_validator.rb +0 -7
@@ -1,19 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class Cleanup
4
- def self.run
5
- raise 'Task not available on production' if Rails.env.production?
6
- Dir[Rails.root.join('app/models/*.rb').to_s].each do |filename|
7
- delete_by_class(filename)
8
- end
9
- end
10
-
11
- def self.delete_by_class(filename)
12
- klass = File.basename(filename, '.rb').camelize.constantize
13
- return unless klass.included_modules.include? DynamoRecord::Model
14
- Rails.logger.info "Deleting all items in table: #{klass}"
15
- klass.scan.each(&:delete!)
16
- end
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class DropAllTables
4
- def self.run(override = false)
5
- raise 'Task not available on production' if Rails.env.production?
6
- env = Rails.env
7
- dynamodb = Aws::DynamoDB::Client.new
8
- tables = dynamodb.list_tables
9
- tables.table_names.map do |t|
10
- next unless t.include?(env) || override
11
- dt = dynamodb.delete_table(table_name: t)
12
- dt ? "Deleted: #{t}" : "Delete failed: #{t}"
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class DropTable
4
- def self.run(table_name)
5
- dynamodb = Aws::DynamoDB::Client.new
6
- resp = dynamodb.delete_table(table_name: table_name)
7
- "Deleted: #{resp.table_description.table_name}"
8
- end
9
- end
10
- end
11
- end
@@ -1,13 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class ListTables
4
- def self.run
5
- dynamodb = Aws::DynamoDB::Client.new
6
- tables = dynamodb.list_tables
7
- tables.table_names.select do |tn|
8
- tn.starts_with?(Rails.configuration.dynamo['prefix'])
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,70 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class MigrationRunner
4
- def self.run(path = 'db/dynamo_migrate')
5
- constants = []
6
- filename_regexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/
7
-
8
- # Sorts the files located in `db/dynamo_migrate` to ensure order is preserved
9
- Dir[Rails.root.join("#{path}/*.rb")].sort.each do |f|
10
- migration = migration(f, filename_regexp, constants)
11
-
12
- # starts the migration
13
- yield "Migrating: #{migration}"
14
-
15
- begin
16
- status = table_config_check(migration)
17
- yield status if status
18
-
19
- status = up(migration)
20
- yield status if status
21
-
22
- status = update(migration)
23
- yield status if status
24
- rescue => e
25
- yield "Migration failed: #{e}"
26
- end
27
- end
28
- end
29
-
30
- def self.migration(f, filename_regexp, constants)
31
- raise "Non-numeric prefix: #{f}" if File.basename(f).scan(filename_regexp).first.nil?
32
- require f
33
-
34
- # finds the constant that was added on the require statement above
35
- migration_sym = (DynamoMigrate.constants - constants).first
36
- migration = DynamoMigrate.const_get(migration_sym)
37
- constants.push migration_sym
38
- migration
39
- end
40
-
41
- def self.status_message(status)
42
- case status
43
- when :exists
44
- 'Table already exists'
45
- when :migrated
46
- 'Migration successful'
47
- else
48
- raise 'Migration failed'
49
- end
50
- end
51
-
52
- def self.up(migration)
53
- return unless migration.respond_to? :up
54
- status_message migration.up
55
- end
56
-
57
- def self.table_config_check(migration)
58
- return unless migration.respond_to? :table_config
59
- status_message migration.table_config_check
60
- end
61
-
62
- def self.update(migration)
63
- return unless migration.respond_to? :update
64
- status = migration.update
65
- return 'Migration successful' if status == :updated
66
- status
67
- end
68
- end
69
- end
70
- end
@@ -1,86 +0,0 @@
1
- module DynamoRecord
2
- module TaskHelpers
3
- class Scale
4
- attr_reader :model, :attribute_selector, :new_throughput
5
- attr_reader :migration, :existing_throughput, :model_name
6
-
7
- def initialize(model_name, attribute_selector, new_throughput)
8
- @model_name = model_name
9
- @attribute_selector = attribute_selector
10
- @new_throughput = new_throughput
11
- end
12
-
13
- def run
14
- return description if [model_name, attribute_selector, new_throughput].any?(&:nil?)
15
-
16
- @model = model_name.constantize
17
- @migration = Aws::Record::TableMigration.new(model)
18
- @existing_throughput = model.provisioned_throughput
19
-
20
- update_throughput
21
- success_message
22
- end
23
-
24
- private
25
-
26
- def success_message
27
- "Successfully updated #{model.table_name} throughput to #{update_instructions[:provisioned_throughput]}"
28
- end
29
-
30
- def update_throughput
31
- raise_attribute_error if !read? && !write?
32
-
33
- migration.update!(update_instructions)
34
- end
35
-
36
- def update_instructions
37
- {
38
- provisioned_throughput: {
39
- write_capacity_units: (write? && new_throughput) || existing_write,
40
- read_capacity_units: (read? && new_throughput) || existing_read
41
- }
42
- }
43
- end
44
-
45
- def existing_write
46
- existing_throughput[:write_capacity_units]
47
- end
48
-
49
- def existing_read
50
- existing_throughput[:read_capacity_units]
51
- end
52
-
53
- def both?
54
- attribute_selector.to_sym == :both
55
- end
56
-
57
- def read?
58
- both? || attribute_selector.to_sym == :read
59
- end
60
-
61
- def write?
62
- both? || attribute_selector.to_sym == :write
63
- end
64
-
65
- def raise_attribute_error
66
- raise ArgumentError, 'You didn\'t provide an appropriate attribute selection. We accept [:both, :read, :write]'
67
- end
68
-
69
- def description
70
- <<~DESCRIPTION
71
- --------------------------------------------------------------------------------
72
- Here's some usage information:
73
- Scale a dynamo table. Requires three inputs.
74
- - ModelName
75
- ruby class of the model
76
- - attribute
77
- valid values include "both", "read" and "write"
78
- - new_throughput
79
- numerical value for the new read/write capacity units
80
- Example: `rake dynamo:scale[MySuperDynamoModel,both,50]`
81
- --------------------------------------------------------------------------------
82
- DESCRIPTION
83
- end
84
- end
85
- end
86
- end
@@ -1,7 +0,0 @@
1
- require 'active_model'
2
- class ModelExistenceValidator < ActiveModel::EachValidator
3
- def validate_each(record, attribute, value)
4
- return if options[:model].exists? value
5
- record.errors[attribute] << (options[:message] || "#{attribute}:#{value} is not a valid #{options[:model]}")
6
- end
7
- end