aurora-data-api 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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.rake_tasks~ +10 -0
  3. data/.standard.yml +6 -0
  4. data/CHANGELOG.md +3 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Gemfile +15 -0
  7. data/Gemfile.lock +103 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +236 -0
  10. data/Rakefile +18 -0
  11. data/Steepfile +5 -0
  12. data/aurora-data-api.gemspec +34 -0
  13. data/example/.gitignore +58 -0
  14. data/example/.ruby-version +1 -0
  15. data/example/Dockerfile +26 -0
  16. data/example/Gemfile +9 -0
  17. data/example/Gemfile.lock +48 -0
  18. data/example/README.md +45 -0
  19. data/example/Rakefile +48 -0
  20. data/example/app/depots/comment_depot.rb +6 -0
  21. data/example/app/depots/entry_depot.rb +6 -0
  22. data/example/app/depots/user_depot.rb +6 -0
  23. data/example/app/handlers/main.rb +86 -0
  24. data/example/app/models/comment.rb +10 -0
  25. data/example/app/models/entry.rb +12 -0
  26. data/example/app/models/user.rb +13 -0
  27. data/example/compose.yml +43 -0
  28. data/example/db/.gitignore +2 -0
  29. data/example/db/.keep +0 -0
  30. data/example/package-lock.json +4740 -0
  31. data/example/package.json +17 -0
  32. data/example/serverless.yml +184 -0
  33. data/exe/aurora-data-api +161 -0
  34. data/lib/aurora-data-api/data_service.rb +42 -0
  35. data/lib/aurora-data-api/depot.rb +132 -0
  36. data/lib/aurora-data-api/environment.rb +41 -0
  37. data/lib/aurora-data-api/model.rb +152 -0
  38. data/lib/aurora-data-api/version.rb +5 -0
  39. data/lib/aurora-data-api.rb +14 -0
  40. data/sig/aurora-data-api.rbs +20 -0
  41. data/sig/data_service.rbs +7 -0
  42. data/sig/depot.rbs +23 -0
  43. data/sig/environment.rbs +13 -0
  44. data/sig/model.rbs +39 -0
  45. data/sig/version.rbs +3 -0
  46. metadata +120 -0
@@ -0,0 +1,48 @@
1
+ GIT
2
+ remote: https://github.com/hasumikin/aurora-data-api.git
3
+ revision: 70ae5070c8391c6be2ac9b4209425308ed01f2e7
4
+ specs:
5
+ aurora-data-api (0.1.0)
6
+ aws-sdk-rdsdataservice (~> 1.35.0)
7
+ thor
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ aws-eventstream (1.2.0)
13
+ aws-partitions (1.594.0)
14
+ aws-sdk-core (3.131.1)
15
+ aws-eventstream (~> 1, >= 1.0.2)
16
+ aws-partitions (~> 1, >= 1.525.0)
17
+ aws-sigv4 (~> 1.1)
18
+ jmespath (~> 1, >= 1.6.1)
19
+ aws-sdk-lambda (1.84.0)
20
+ aws-sdk-core (~> 3, >= 3.127.0)
21
+ aws-sigv4 (~> 1.1)
22
+ aws-sdk-rdsdataservice (1.35.0)
23
+ aws-sdk-core (~> 3, >= 3.127.0)
24
+ aws-sigv4 (~> 1.1)
25
+ aws-sigv4 (1.5.0)
26
+ aws-eventstream (~> 1, >= 1.0.2)
27
+ jmespath (1.6.1)
28
+ power_assert (2.0.1)
29
+ rake (13.0.6)
30
+ rr (3.0.9)
31
+ test-unit (3.5.3)
32
+ power_assert
33
+ test-unit-rr (1.0.5)
34
+ rr (>= 1.1.1)
35
+ test-unit (>= 2.5.2)
36
+ thor (1.2.1)
37
+
38
+ PLATFORMS
39
+ x86_64-linux
40
+
41
+ DEPENDENCIES
42
+ aurora-data-api!
43
+ aws-sdk-lambda
44
+ rake
45
+ test-unit-rr
46
+
47
+ BUNDLED WITH
48
+ 2.3.14
data/example/README.md ADDED
@@ -0,0 +1,45 @@
1
+ ## Example app
2
+
3
+ ### Stack
4
+
5
+ - Serverless Framework
6
+ - Lamdda functions (outside VPC)
7
+ - RDS Aurora Serverless v1 (inside VPC) +
8
+
9
+ ### Getting started
10
+
11
+ ```sh
12
+ docker compose build
13
+ docker compose run --rm serverless rake db:create_database
14
+ docker compose run --rm serverless bundle exec aurora-data-api export
15
+ docker compose run --rm serverless rake db:migrate_dry_run
16
+ docker compose run --rm serverless rake db:migrate
17
+ ```
18
+ ```sh
19
+ docker compose run --rm serverless rake db:migrate_dry_run
20
+ => -- Nothing is modified --
21
+ ```
22
+ ```sh
23
+ docker compose up
24
+ ```
25
+ ```sh
26
+ curl http://localhost:4000/offline/hello
27
+ ```
28
+
29
+ ```sh
30
+ curl -X POST http://localhost:4000/offline/create_user \
31
+ -H 'Content-Type: application/json' \
32
+ -d '{"name":"HASUMI Hitoshi", "internet_account":"hasumikin"}'
33
+
34
+ curl -X PUT http://localhost:4000/offline/update_user \
35
+ -H 'Content-Type: application/json' \
36
+ -d '{"id":1, "name":"anonymous", "internet_account":"hasumikin"}'
37
+
38
+ curl -X POST http://localhost:4000/offline/create_entry \
39
+ -H 'Content-Type: application/json' \
40
+ -d '{"title":"My first atrticle", "user_id":1}'
41
+
42
+ curl -X POST http://localhost:4000/offline/delete_entry \
43
+ -H 'Content-Type: application/json' \
44
+ -d '{"entry_id":1}'
45
+ ```
data/example/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+
2
+ namespace "db" do
3
+ desc "Create database"
4
+ task :create_database do
5
+ sql = <<~SQL
6
+ CREATE DATABASE #{ENV['PGDATABASE']}
7
+ TEMPLATE template0 ENCODING 'UTF-8' LC_COLLATE 'C' LC_CTYPE 'C';
8
+ SQL
9
+ sh "psql postgres -c \"#{sql}\""
10
+ end
11
+
12
+ desc "Drop database"
13
+ task :drop_database do
14
+ sql = <<~SQL
15
+ DROP DATABASE #{ENV['PGDATABASE']};
16
+ SQL
17
+ sh "psql postgres -c \"#{sql}\""
18
+ end
19
+
20
+ desc "Migrate schema"
21
+ task :migrate do
22
+ Rake::Task['db:__migrate'].invoke("")
23
+ end
24
+
25
+ desc "Migrate schema (--dry-run)"
26
+ task :migrate_dry_run do
27
+ Rake::Task['db:__migrate'].invoke("--dry-run")
28
+ end
29
+
30
+ task :__migrate, ['opt'] do |_t, args|
31
+ sh <<~CMD
32
+ bundle exec aurora-data-api export && \
33
+ /home/ec2-user/bin/psqldef -h #{ENV['PGHOST']} #{ENV['PGDATABASE']} #{args.opt} < ./db/schema.sql
34
+ CMD
35
+ end
36
+
37
+ desc "Export schema"
38
+ task :export do
39
+ sh "/home/ec2-user/bin/psqldef -h #{ENV['PGHOST']} #{ENV['PGDATABASE']} --export"
40
+ end
41
+
42
+ desc "List database"
43
+ task :list_database do
44
+ sh "psql postgres -c " + <<~SQL
45
+ 'select datname, datdba, encoding, datcollate, datctype from pg_database;'
46
+ SQL
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/comment'
4
+
5
+ CommentDepot = AuroraDataApi::Depot[Comment] do
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/entry'
4
+
5
+ EntryDepot = AuroraDataApi::Depot[Entry] do
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/user'
4
+
5
+ UserDepot = AuroraDataApi::Depot[User] do
6
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob("/var/runtime/bundler/gems/**").each do |dir|
4
+ $LOAD_PATH.unshift("#{dir}/lib/")
5
+ end
6
+
7
+ require "json"
8
+ require "aurora-data-api"
9
+ require_relative "../depots/user_depot"
10
+ require_relative "../depots/entry_depot"
11
+ require_relative "../depots/comment_depot"
12
+
13
+ def hello(event:, context:)
14
+ {
15
+ statusCode: 200,
16
+ body: { message: "Hello" }.to_json
17
+ }
18
+ end
19
+
20
+ def users(event:, context:)
21
+ users = UserDepot.select("order by id limit 10")
22
+ {
23
+ statusCode: 200,
24
+ body: { users: users.map(&:attributes) }.to_json
25
+ }
26
+ end
27
+
28
+ def create_user(event:, context:)
29
+ params = JSON.parse(event["body"])
30
+ user = User.new(**params)
31
+ UserDepot.insert(user)
32
+ {
33
+ statusCode: 201,
34
+ body: { user: user.attributes }.to_json
35
+ }
36
+ end
37
+
38
+ def update_user(event:, context:)
39
+ params = JSON.parse(event["body"])
40
+ user = UserDepot.select("where id = :id", id: params["id"]).first
41
+ user.name = params["name"]
42
+ user.internet_account = params["internet_account"]
43
+ UserDepot.update(user)
44
+ {
45
+ statusCode: 201,
46
+ body: { user: user.attributes }.to_json
47
+ }
48
+ end
49
+
50
+ def count_entry(event:, context:)
51
+ count = EntryDepot.count
52
+ {
53
+ statusCode: 200,
54
+ body: { count: count }.to_json
55
+ }
56
+ end
57
+
58
+ def entries(event:, context:)
59
+ entries = EntryDepot.select(
60
+ "inner join users on users.id = entries.user_id order by entries.id limit 10"
61
+ )
62
+ #
63
+ # (Note) This also works but N+1 query happens:
64
+ # EntryDepot.select("order by id limit 10")
65
+ #
66
+ {
67
+ statusCode: 200,
68
+ body: { entries: entries.map(&:attributes) }.to_json
69
+ }
70
+ end
71
+
72
+ def create_entry(event:, context:)
73
+ params = JSON.parse(event["body"])
74
+ entry = Entry.new(**params)
75
+ EntryDepot.insert(entry)
76
+ {
77
+ statusCode: 201,
78
+ body: { entry: entry.attributes }.to_json
79
+ }
80
+ end
81
+
82
+ def delete_entry(event:, context:)
83
+ entry_id = JSON.parse(event["body"])["entry_id"]
84
+ entry = EntryDepot.select('where id = :id', id: entry_id)[0]
85
+ EntryDepot.delete(entry)
86
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Comment < AuroraDataApi::Model
4
+ schema do
5
+ col :user, :User, table: :users, null: false
6
+ col :entry, :Entry, table: :entries, null: false
7
+ col :body, String
8
+ timestamp
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Entry < AuroraDataApi::Model
4
+ table :entries
5
+ schema do
6
+ col :user, :User, table: :users, null: false
7
+ col :title, String
8
+ col :body, String
9
+ timestamp
10
+ end
11
+ end
12
+
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class User < AuroraDataApi::Model
4
+ schema do
5
+ col :name, String
6
+ col :internet_account, String
7
+ timestamp
8
+ end
9
+
10
+ def twitter
11
+ "https://twitter.com/#{internet_account}"
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ services:
2
+ serverless:
3
+ build:
4
+ context: .
5
+ dockerfile: Dockerfile
6
+ command: bash -c "npx sls offline --host 0.0.0.0"
7
+ ports:
8
+ - "4000:4000"
9
+ stdin_open: true
10
+ tty: true
11
+ volumes:
12
+ - .:/app
13
+ depends_on:
14
+ - local-data-api
15
+ environment:
16
+ # needed in Rake tasks
17
+ IS_OFFLINE: "true"
18
+ TZ: Asia/Tokyo
19
+ PGUSER: postgres
20
+ PGPASSWORD: password
21
+ PGHOST: db
22
+ PGPORT: 5432
23
+ PGDATABASE: mydatabase
24
+ local-data-api:
25
+ image: koxudaxi/local-data-api
26
+ environment:
27
+ ENGINE: PostgreSQLJDBC
28
+ POSTGRES_HOST: db
29
+ POSTGRES_PORT: 5432
30
+ POSTGRES_USER: postgres
31
+ POSTGRES_PASSWORD: password
32
+ depends_on:
33
+ - db
34
+ ports:
35
+ - "8080:80"
36
+ db:
37
+ image: postgres:10.7-alpine
38
+ environment:
39
+ POSTGRES_PASSWORD: password
40
+ POSTGRES_DB: mydatabase
41
+ ports:
42
+ - "5432:5432"
43
+
@@ -0,0 +1,2 @@
1
+ schema.sql
2
+ !.keep
data/example/db/.keep ADDED
File without changes