Browse Source

[ruby/hanami] Update to Hanami 2.2 (#9685)

Move setting headers to application action.
Use repo's for database operations.
Petrik de Heus 5 months ago
parent
commit
f7401a5935

+ 5 - 4
frameworks/Ruby/hanami/Gemfile

@@ -2,10 +2,11 @@
 
 source "https://rubygems.org"
 
-gem "hanami", "~> 2.0"
-gem "hanami-router", "~> 2.0"
-gem "hanami-controller", "~> 2.0"
-gem "hanami-validations", "~> 2.0"
+gem "hanami", "~> 2.2"
+gem "hanami-router", "~> 2.2"
+gem "hanami-controller", "~> 2.2"
+gem "hanami-db", "~> 2.2"
+gem "hanami-validations", "~> 2.2"
 
 gem "dry-types", "~> 1.0", ">= 1.6.1"
 gem "puma"

+ 50 - 46
frameworks/Ruby/hanami/Gemfile.lock

@@ -2,7 +2,7 @@ GEM
   remote: https://rubygems.org/
   specs:
     bigdecimal (3.1.9)
-    concurrent-ruby (1.3.4)
+    concurrent-ruby (1.3.5)
     dry-auto_inject (1.1.0)
       dry-core (~> 1.1)
       zeitwerk (~> 2.6)
@@ -30,38 +30,38 @@ GEM
       dry-configurable (~> 1.0, < 2)
       dry-core (~> 1.0, < 2)
       dry-events (~> 1.0, < 2)
-    dry-schema (1.13.4)
+    dry-schema (1.14.1)
       concurrent-ruby (~> 1.0)
       dry-configurable (~> 1.0, >= 1.0.1)
-      dry-core (~> 1.0, < 2)
-      dry-initializer (~> 3.0)
-      dry-logic (>= 1.4, < 2)
-      dry-types (>= 1.7, < 2)
-      zeitwerk (~> 2.6)
-    dry-struct (1.7.0)
       dry-core (~> 1.1)
+      dry-initializer (~> 3.2)
+      dry-logic (~> 1.5)
       dry-types (~> 1.8)
+      zeitwerk (~> 2.6)
+    dry-struct (1.8.0)
+      dry-core (~> 1.1)
+      dry-types (~> 1.8, >= 1.8.2)
       ice_nine (~> 0.11)
       zeitwerk (~> 2.6)
-    dry-system (1.2.0)
+    dry-system (1.2.2)
       dry-auto_inject (~> 1.1)
       dry-configurable (~> 1.3)
       dry-core (~> 1.1)
       dry-inflector (~> 1.1)
     dry-transformer (1.0.1)
       zeitwerk (~> 2.6)
-    dry-types (1.8.0)
+    dry-types (1.8.2)
       bigdecimal (~> 3.0)
       concurrent-ruby (~> 1.0)
       dry-core (~> 1.0)
       dry-inflector (~> 1.0)
       dry-logic (~> 1.4)
       zeitwerk (~> 2.6)
-    dry-validation (1.10.0)
+    dry-validation (1.11.1)
       concurrent-ruby (~> 1.0)
-      dry-core (~> 1.0, < 2)
-      dry-initializer (~> 3.0)
-      dry-schema (>= 1.12, < 2)
+      dry-core (~> 1.1)
+      dry-initializer (~> 3.2)
+      dry-schema (~> 1.14)
       zeitwerk (~> 2.6)
     hanami (2.2.1)
       bundler (>= 1.16, < 3)
@@ -82,13 +82,17 @@ GEM
       dry-inflector (~> 1.0, < 2)
       rake (~> 13.0)
       zeitwerk (~> 2.6)
-    hanami-controller (2.1.0)
+    hanami-controller (2.2.0)
       dry-configurable (~> 1.0, < 2)
       dry-core (~> 1.0)
-      hanami-utils (~> 2.1)
+      hanami-utils (~> 2.2)
       rack (~> 2.0)
       zeitwerk (~> 2.6)
-    hanami-router (2.1.0)
+    hanami-db (2.2.1)
+      rom (~> 5.4, >= 5.4.1)
+      rom-sql (~> 3.7)
+      zeitwerk (~> 2.6)
+    hanami-router (2.2.0)
       mustermann (~> 3.0)
       mustermann-contrib (~> 3.0)
       rack (~> 2.0)
@@ -96,13 +100,12 @@ GEM
       concurrent-ruby (~> 1.0)
       dry-core (~> 1.0, < 2)
       dry-transformer (~> 1.0, < 2)
-    hanami-validations (2.1.0)
+    hanami-validations (2.2.0)
       dry-validation (>= 1.10, < 2)
-      zeitwerk (~> 2.6.0)
     hansi (0.2.1)
     ice_nine (0.11.2)
-    json (2.9.1)
-    logger (1.6.4)
+    json (2.10.2)
+    logger (1.6.6)
     mustermann (3.0.3)
       ruby2_keywords (~> 0.0.1)
     mustermann-contrib (3.0.3)
@@ -110,41 +113,41 @@ GEM
       mustermann (= 3.0.3)
     nio4r (2.7.4)
     pg (1.5.9)
-    puma (6.5.0)
+    puma (6.6.0)
       nio4r (~> 2.0)
-    rack (2.2.9)
+    rack (2.2.13)
     rake (13.2.1)
-    rom (5.3.2)
-      rom-changeset (~> 5.3, >= 5.3.0)
-      rom-core (~> 5.3, >= 5.3.2)
-      rom-repository (~> 5.3, >= 5.3.0)
-    rom-changeset (5.3.0)
+    rom (5.4.2)
+      rom-changeset (~> 5.4)
+      rom-core (~> 5.4)
+      rom-repository (~> 5.4, >= 5.4.2)
+    rom-changeset (5.4.0)
       dry-core (~> 1.0)
-      rom-core (~> 5.3)
-      transproc (~> 1.0, >= 1.1.0)
-    rom-core (5.3.2)
+      rom-core (~> 5.4)
+      transproc (~> 1.1)
+    rom-core (5.4.0)
       concurrent-ruby (~> 1.1)
       dry-configurable (~> 1.0)
       dry-core (~> 1.0)
       dry-inflector (~> 1.0)
-      dry-initializer (~> 3.0, >= 3.0.1)
+      dry-initializer (~> 3.2)
       dry-struct (~> 1.0)
       dry-types (~> 1.6)
-      transproc (~> 1.0, >= 1.1.0)
-    rom-repository (5.3.0)
-      dry-core (~> 1.0)
-      dry-initializer (~> 3.0, >= 3.0.1)
-      rom-core (~> 5.3, >= 5.3.0)
-    rom-sql (3.6.5)
+      transproc (~> 1.1)
+    rom-repository (5.4.2)
       dry-core (~> 1.0)
-      dry-types (~> 1.0)
-      rom (~> 5.2, >= 5.2.1)
+      dry-initializer (~> 3.2)
+      rom-core (~> 5.4)
+    rom-sql (3.7.0)
+      dry-core (~> 1.1)
+      dry-types (~> 1.8)
+      rom (~> 5.4)
       sequel (>= 4.49)
     ruby2_keywords (0.0.5)
-    sequel (5.88.0)
+    sequel (5.90.0)
       bigdecimal
     transproc (1.1.1)
-    zeitwerk (2.6.18)
+    zeitwerk (2.7.2)
 
 PLATFORMS
   ruby
@@ -152,10 +155,11 @@ PLATFORMS
 
 DEPENDENCIES
   dry-types (~> 1.0, >= 1.6.1)
-  hanami (~> 2.0)
-  hanami-controller (~> 2.0)
-  hanami-router (~> 2.0)
-  hanami-validations (~> 2.0)
+  hanami (~> 2.2)
+  hanami-controller (~> 2.2)
+  hanami-db (~> 2.2)
+  hanami-router (~> 2.2)
+  hanami-validations (~> 2.2)
   pg
   puma
   rake

+ 2 - 0
frameworks/Ruby/hanami/Procfile.dev

@@ -0,0 +1,2 @@
+web: bundle exec hanami server
+# assets: bundle exec hanami assets watch

+ 8 - 0
frameworks/Ruby/hanami/app/action.rb

@@ -5,5 +5,13 @@ require "hanami/action"
 
 module HelloWorld
   class Action < Hanami::Action
+    before :set_headers
+
+    private
+
+    def set_headers(*, response)
+      response.headers['Server'] = 'hanami'
+      response.headers['Date'] = Time.now.httpdate
+    end
   end
 end

+ 4 - 5
frameworks/Ruby/hanami/app/actions/db/index.rb

@@ -5,14 +5,13 @@ module HelloWorld
     module DB
       class Index < HelloWorld::Action
         QUERY_RANGE = 1..10_000    # range of IDs in the Fortune DB
-        include Deps["persistence.rom"]
+
+        include Deps["repos.world_repo"]
 
         def handle(*, response)
-          world = rom.relations[:World].by_pk(random_id).one
-          response.headers['Server'] = 'hanami'
-          response.headers['Date'] = Time.now.httpdate
+          world = world_repo.find(random_id)
           response.format = :json
-          response.body = world.to_json
+          response.body = world.to_h.to_json
         end
 
         def random_id

+ 0 - 2
frameworks/Ruby/hanami/app/actions/json/index.rb

@@ -5,8 +5,6 @@ module HelloWorld
     module JSON
       class Index < HelloWorld::Action
         def handle(*, response)
-          response.headers['Server'] = 'hanami'
-          response.headers['Date'] = Time.now.httpdate
           response.format = :json
           response.body = { 'message' => 'Hello, World!' }.to_json
         end

+ 0 - 2
frameworks/Ruby/hanami/app/actions/plaintext/index.rb

@@ -5,8 +5,6 @@ module HelloWorld
     module Plaintext
       class Index < HelloWorld::Action
         def handle(*, response)
-          response.headers['Server'] = 'hanami'
-          response.headers['Date'] = Time.now.httpdate
           response.body = 'Hello, World!'
         end
       end

+ 3 - 5
frameworks/Ruby/hanami/app/actions/queries/index.rb

@@ -9,16 +9,14 @@ module HelloWorld
         MIN_QUERIES = 1            # min number of records that can be retrieved
         MAX_QUERIES = 500          # max number of records that can be retrieved
 
-        include Deps["persistence.rom"]
+        include Deps["repos.world_repo"]
 
         def handle(request, response)
           worlds = ALL_IDS.sample(queries(request)).map do |id|
-            rom.relations[:World].by_pk(id).one
+            world_repo.find(id)
           end
-          response.headers['Server'] = 'hanami'
-          response.headers['Date'] = Time.now.httpdate
           response.format = :json
-          response.body = worlds.to_json
+          response.body = worlds.map(&:to_h).to_json
         end
 
         private

+ 2 - 10
frameworks/Ruby/hanami/app/actions/updates/index.rb

@@ -9,20 +9,12 @@ module HelloWorld
         MIN_QUERIES = 1            # min number of records that can be retrieved
         MAX_QUERIES = 500          # max number of records that can be retrieved
 
-        include Deps["persistence.rom"]
+        include Deps["repos.world_repo"]
 
         def handle(request, response)
           worlds = ALL_IDS.sample(queries(request)).map do |id|
-            world = rom.relations[:World].by_pk(id)
-            world_struct = world.one
-            new_value = random_id
-            new_value = random_id while new_value == world_struct[:randomnumber]
-            world_struct[:randomnumber] = new_value
-            world.command(:update).call(randomnumber: world_struct[:randomnumber])
-            world_struct
+            world_repo.update(id)
           end
-          response.headers['Server'] = 'hanami'
-          response.headers['Date'] = Time.now.httpdate
           response.format = :json
           response.body = worlds.to_json
         end

+ 10 - 0
frameworks/Ruby/hanami/app/db/relation.rb

@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require "hanami/db/relation"
+
+module HelloWorld
+  module DB
+    class Relation < Hanami::DB::Relation
+    end
+  end
+end

+ 10 - 0
frameworks/Ruby/hanami/app/db/repo.rb

@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require "hanami/db/repo"
+
+module HelloWorld
+  module DB
+    class Repo < Hanami::DB::Repo
+    end
+  end
+end

+ 10 - 0
frameworks/Ruby/hanami/app/db/struct.rb

@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require "hanami/db/struct"
+
+module HelloWorld
+  module DB
+    class Struct < Hanami::DB::Struct
+    end
+  end
+end

+ 0 - 0
frameworks/Ruby/hanami/app/relations/.keep


+ 7 - 0
frameworks/Ruby/hanami/app/relations/worlds.rb

@@ -0,0 +1,7 @@
+module HelloWorld
+  module Relations
+    class Worlds < HelloWorld::DB::Relation
+      schema :World, infer: true, as: :worlds
+    end
+  end
+end

+ 0 - 0
frameworks/Ruby/hanami/app/repos/.keep


+ 27 - 0
frameworks/Ruby/hanami/app/repos/world_repo.rb

@@ -0,0 +1,27 @@
+module HelloWorld
+  module Repos
+    class WorldRepo < HelloWorld::DB::Repo
+      QUERY_RANGE = 1..10_000    # range of IDs in the Fortune DB
+
+      def find(id)
+        worlds.by_pk(id).one
+      end
+
+      def update(id)
+        world = worlds.by_pk(id)
+        world_hash = world.one.to_h
+        new_value = random_id
+        new_value = random_id while new_value == world_hash[:randomnumber]
+        world_hash[:randomnumber] = new_value
+        world.changeset(:update, **world_hash).commit
+        world_hash
+      end
+
+      private
+
+        def random_id
+          Random.rand(QUERY_RANGE)
+        end
+    end
+  end
+end

+ 0 - 0
frameworks/Ruby/hanami/app/structs/.keep


+ 11 - 0
frameworks/Ruby/hanami/app/templates/layouts/app.html.erb

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Bookshelf</title>
+  </head>
+  <body>
+    <%= yield %>
+  </body>
+</html>

+ 9 - 0
frameworks/Ruby/hanami/app/view.rb

@@ -0,0 +1,9 @@
+# auto_register: false
+# frozen_string_literal: true
+
+require "hanami/view"
+
+module HelloWorld
+  class View < Hanami::View
+  end
+end

+ 0 - 32
frameworks/Ruby/hanami/config/providers/persistence.rb

@@ -1,32 +0,0 @@
-Hanami.app.register_provider :persistence, namespace: true do
-  prepare do
-    require "rom"
-
-    require_relative '../auto_tune'
-    num_workers, num_threads = auto_tune
-
-    opts = {
-      max_connections: 3,
-      pool_timeout: 10
-    }
-    config = ROM::Configuration.new(:sql, target["settings"].database_url, opts)
-
-    register "config", config
-    register "db", config.gateways[:default].connection
-  end
-
-  start do
-    config = target["persistence.config"]
-
-    config.auto_registration(
-      target.root.join("lib/hello_world/persistence"),
-      namespace: "HelloWorld::Persistence"
-    )
-
-    register "rom", ROM.container(config)
-  end
-
-  stop do
-    target["persistence.rom"].disconnect
-  end
-end

+ 0 - 9
frameworks/Ruby/hanami/lib/hello_world/persistence/relations/world.rb

@@ -1,9 +0,0 @@
-module HelloWorld
-  module Persistence
-    module Relations
-      class World < ROM::Relation[:sql]
-        schema(:World, infer: true)
-      end
-    end
-  end
-end