server-postgres.cr 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. require "kemal"
  2. require "pg"
  3. require "pool/connection"
  4. # Compose Objects (like Hash) to have a to_json method
  5. require "json/to_json"
  6. DB = ConnectionPool.new(capacity: 25, timeout: 0.01) do
  7. PG.connect("postgres://benchmarkdbuser:benchmarkdbpass@#{ENV["DBHOST"]? || "127.0.0.1"}/hello_world")
  8. end
  9. class CONTENT
  10. UTF8 = "; charset=UTF-8"
  11. JSON = "application/json"
  12. PLAIN = "text/plain"
  13. HTML = "text/html" + UTF8
  14. end
  15. ID_MAXIMUM = 10_000
  16. private def random_world
  17. id = rand(1..ID_MAXIMUM)
  18. conn = DB.checkout
  19. result = conn.exec({Int32, Int32}, "SELECT id, randomNumber FROM world WHERE id = $1", [id]).rows.first
  20. DB.checkin(conn)
  21. {id: result[0], randomNumber: result[1]}
  22. end
  23. private def set_world(world)
  24. conn = DB.checkout
  25. result = conn.exec("UPDATE world set randomNumber = $1 where id = $2", [world[:randomNumber], world[:id]])
  26. DB.checkin(conn)
  27. world
  28. end
  29. private def fortunes
  30. data = [] of NamedTuple(id: Int32, message: String)
  31. DB.connection.exec({Int32, String}, "select id, message from Fortune").rows.each do |row|
  32. data.push({id: row[0], message: row[1]})
  33. end
  34. data
  35. end
  36. private def sanitized_query_count(request)
  37. queries = request.params.query["queries"].as(String)
  38. queries = queries.to_i? || 1
  39. queries.clamp(1..500)
  40. end
  41. before_all do |env|
  42. env.response.headers["Server"] = "Kemal"
  43. env.response.headers["Date"] = Time.now.to_s
  44. end
  45. #
  46. # Basic Tests
  47. #
  48. # Test 1: JSON Serialization
  49. get "/json" do |env|
  50. env.response.content_type = CONTENT::JSON
  51. {message: "Hello, World!"}.to_json
  52. end
  53. # Test 6: Plaintext
  54. get "/plaintext" do |env|
  55. env.response.content_type = CONTENT::PLAIN
  56. "Hello, World!"
  57. end
  58. #
  59. # Postgres DatabaseTests
  60. #
  61. # Postgres Test 2: Single database query
  62. get "/db" do |env|
  63. env.response.content_type = CONTENT::JSON
  64. random_world.to_json
  65. end
  66. # Postgres Test 3: Multiple database query
  67. get "/queries" do |env|
  68. results = (1..sanitized_query_count(env)).map do
  69. random_world
  70. end
  71. env.response.content_type = CONTENT::JSON
  72. results.to_json
  73. end
  74. # Postgres Test 4: Fortunes
  75. get "/fortunes" do |env|
  76. env.response.content_type = CONTENT::HTML
  77. data = fortunes
  78. additional_fortune = {
  79. id: 0,
  80. message: "Additional fortune added at request time.",
  81. }
  82. data.push(additional_fortune)
  83. data.sort_by! { |fortune| fortune[:message] }
  84. render "views/fortunes.ecr"
  85. end
  86. # Postgres Test 5: Database Updates
  87. get "/updates" do |env|
  88. updated = (1..sanitized_query_count(env)).map do
  89. set_world({id: random_world[:id], randomNumber: rand(1..ID_MAXIMUM)})
  90. end
  91. env.response.content_type = CONTENT::JSON
  92. updated.to_json
  93. end
  94. logging false
  95. Kemal.run