serrano-vk 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 (588) hide show
  1. checksums.yaml +7 -0
  2. data/EXAMPLES.md +271 -0
  3. data/README.md +170 -0
  4. data/bin/serrano +6 -0
  5. data/examples/demo_crud/Gemfile +9 -0
  6. data/examples/demo_crud/Gemfile.lock +31 -0
  7. data/examples/demo_crud/app/controllers/articles_controller.rb +92 -0
  8. data/examples/demo_crud/app/controllers/categories_controller.rb +92 -0
  9. data/examples/demo_crud/app/entities/article.rb +17 -0
  10. data/examples/demo_crud/app/entities/category.rb +17 -0
  11. data/examples/demo_crud/app/entities/concerns/validatable.rb +136 -0
  12. data/examples/demo_crud/app/repositories/article_repository.rb +42 -0
  13. data/examples/demo_crud/app/repositories/category_repository.rb +42 -0
  14. data/examples/demo_crud/app/services/articles/create.rb +29 -0
  15. data/examples/demo_crud/app/services/articles/destroy.rb +20 -0
  16. data/examples/demo_crud/app/services/articles/index.rb +17 -0
  17. data/examples/demo_crud/app/services/articles/show.rb +20 -0
  18. data/examples/demo_crud/app/services/articles/update.rb +26 -0
  19. data/examples/demo_crud/app/services/categories/create.rb +27 -0
  20. data/examples/demo_crud/app/services/categories/destroy.rb +20 -0
  21. data/examples/demo_crud/app/services/categories/index.rb +17 -0
  22. data/examples/demo_crud/app/services/categories/show.rb +20 -0
  23. data/examples/demo_crud/app/services/categories/update.rb +26 -0
  24. data/examples/demo_crud/config/db.rb +3 -0
  25. data/examples/demo_crud/config.ru +19 -0
  26. data/examples/demo_crud/db/development.sqlite3 +0 -0
  27. data/examples/demo_crud/db/migrations/20260307212844_create_articles.rb +14 -0
  28. data/examples/demo_crud/db/migrations/20260307212845_create_categories.rb +12 -0
  29. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/rackup +29 -0
  30. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/rackup.bat +2 -0
  31. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/sequel +29 -0
  32. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/sequel.bat +2 -0
  33. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/serrano +29 -0
  34. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/bin/serrano.bat +2 -0
  35. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/bigdecimal-4.0.1.gem +0 -0
  36. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/rack-3.2.5.gem +0 -0
  37. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/rackup-2.3.1.gem +0 -0
  38. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/sequel-5.102.0.gem +0 -0
  39. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/sqlite3-2.9.1-x64-mingw-ucrt.gem +0 -0
  40. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/cache/webrick-1.9.2.gem +0 -0
  41. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/extensions/x64-mingw-ucrt/3.4.0/bigdecimal-4.0.1/bigdecimal.so +0 -0
  42. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/extensions/x64-mingw-ucrt/3.4.0/bigdecimal-4.0.1/gem.build_complete +0 -0
  43. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/extensions/x64-mingw-ucrt/3.4.0/bigdecimal-4.0.1/gem_make.out +43 -0
  44. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/extensions/x64-mingw-ucrt/3.4.0/bigdecimal-4.0.1/mkmf.log +669 -0
  45. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/LICENSE +56 -0
  46. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/bigdecimal.gemspec +57 -0
  47. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/Makefile +278 -0
  48. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/bigdecimal.c +6206 -0
  49. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/bigdecimal.h +292 -0
  50. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/bits.h +144 -0
  51. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/extconf.rb +60 -0
  52. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/feature.h +68 -0
  53. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/missing/dtoa.c +3462 -0
  54. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/missing.c +28 -0
  55. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/missing.h +104 -0
  56. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/ext/bigdecimal/static_assert.h +54 -0
  57. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal/jacobian.rb +92 -0
  58. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal/ludcmp.rb +91 -0
  59. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal/math.rb +948 -0
  60. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal/newton.rb +82 -0
  61. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal/util.rb +186 -0
  62. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal.rb +360 -0
  63. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/lib/bigdecimal.so +0 -0
  64. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/sample/linear.rb +74 -0
  65. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/sample/nlsolve.rb +40 -0
  66. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.0.1/sample/pi.rb +21 -0
  67. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/CHANGELOG.md +1314 -0
  68. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/CONTRIBUTING.md +144 -0
  69. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/MIT-LICENSE +20 -0
  70. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/README.md +384 -0
  71. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/SPEC.rdoc +258 -0
  72. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/auth/abstract/handler.rb +41 -0
  73. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/auth/abstract/request.rb +51 -0
  74. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/auth/basic.rb +58 -0
  75. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/bad_request.rb +8 -0
  76. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/body_proxy.rb +63 -0
  77. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/builder.rb +296 -0
  78. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/cascade.rb +67 -0
  79. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/common_logger.rb +89 -0
  80. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/conditional_get.rb +87 -0
  81. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/config.rb +22 -0
  82. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/constants.rb +68 -0
  83. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/content_length.rb +34 -0
  84. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/content_type.rb +33 -0
  85. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/deflater.rb +158 -0
  86. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/directory.rb +208 -0
  87. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/etag.rb +71 -0
  88. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/events.rb +172 -0
  89. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/files.rb +216 -0
  90. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/head.rb +25 -0
  91. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/headers.rb +238 -0
  92. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/lint.rb +964 -0
  93. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/lock.rb +29 -0
  94. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/media_type.rb +52 -0
  95. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/method_override.rb +56 -0
  96. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/mime.rb +694 -0
  97. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/mock.rb +3 -0
  98. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/mock_request.rb +161 -0
  99. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/mock_response.rb +156 -0
  100. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/multipart/generator.rb +99 -0
  101. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/multipart/parser.rb +580 -0
  102. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/multipart/uploaded_file.rb +82 -0
  103. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/multipart.rb +77 -0
  104. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/null_logger.rb +48 -0
  105. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/query_parser.rb +261 -0
  106. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/recursive.rb +66 -0
  107. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/reloader.rb +112 -0
  108. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/request.rb +790 -0
  109. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/response.rb +403 -0
  110. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/rewindable_input.rb +116 -0
  111. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/runtime.rb +35 -0
  112. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/sendfile.rb +197 -0
  113. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/show_exceptions.rb +409 -0
  114. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/show_status.rb +121 -0
  115. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/static.rb +188 -0
  116. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/tempfile_reaper.rb +33 -0
  117. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/urlmap.rb +99 -0
  118. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/utils.rb +622 -0
  119. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack/version.rb +17 -0
  120. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rack-3.2.5/lib/rack.rb +64 -0
  121. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/bin/rackup +5 -0
  122. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/handler/cgi.rb +61 -0
  123. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/handler/webrick.rb +196 -0
  124. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/handler.rb +113 -0
  125. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/lobster.rb +81 -0
  126. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/server.rb +462 -0
  127. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/stream.rb +199 -0
  128. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup/version.rb +8 -0
  129. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/lib/rackup.rb +21 -0
  130. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/license.md +80 -0
  131. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/readme.md +82 -0
  132. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/releases.md +28 -0
  133. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/rackup-2.3.1/security.md +3 -0
  134. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/MIT-LICENSE +19 -0
  135. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/bin/sequel +280 -0
  136. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/ado/access.rb +335 -0
  137. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/ado/mssql.rb +62 -0
  138. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/ado.rb +283 -0
  139. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/amalgalite.rb +184 -0
  140. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/ibmdb.rb +423 -0
  141. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/db2.rb +83 -0
  142. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/derby.rb +318 -0
  143. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/h2.rb +290 -0
  144. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/hsqldb.rb +228 -0
  145. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/jtds.rb +39 -0
  146. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/mssql.rb +30 -0
  147. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/mysql.rb +89 -0
  148. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/oracle.rb +146 -0
  149. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/postgresql.rb +239 -0
  150. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/sqlanywhere.rb +87 -0
  151. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/sqlite.rb +133 -0
  152. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/sqlserver.rb +92 -0
  153. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc/transactions.rb +95 -0
  154. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/jdbc.rb +850 -0
  155. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/mock.rb +381 -0
  156. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/mysql.rb +380 -0
  157. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/mysql2.rb +307 -0
  158. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/odbc/db2.rb +11 -0
  159. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/odbc/mssql.rb +57 -0
  160. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/odbc/oracle.rb +11 -0
  161. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/odbc.rb +150 -0
  162. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/oracle.rb +427 -0
  163. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/postgres.rb +863 -0
  164. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/postgresql.rb +3 -0
  165. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/access.rb +301 -0
  166. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/db2.rb +509 -0
  167. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/mssql.rb +1238 -0
  168. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/mysql.rb +1175 -0
  169. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/oracle.rb +732 -0
  170. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/postgres.rb +3022 -0
  171. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/sqlanywhere.rb +470 -0
  172. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/shared/sqlite.rb +1073 -0
  173. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/sqlanywhere.rb +192 -0
  174. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/sqlite.rb +475 -0
  175. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/tinytds.rb +259 -0
  176. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/trilogy.rb +116 -0
  177. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  178. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +74 -0
  179. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +93 -0
  180. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  181. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  182. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/replace.rb +35 -0
  183. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/split_alter_table.rb +46 -0
  184. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/stored_procedures.rb +61 -0
  185. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  186. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/ast_transformer.rb +132 -0
  187. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/sharded_single.rb +113 -0
  188. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/sharded_threaded.rb +392 -0
  189. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/sharded_timed_queue.rb +399 -0
  190. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/single.rb +57 -0
  191. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/threaded.rb +307 -0
  192. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool/timed_queue.rb +288 -0
  193. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/connection_pool.rb +175 -0
  194. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/core.rb +476 -0
  195. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/connecting.rb +349 -0
  196. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/dataset.rb +89 -0
  197. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/dataset_defaults.rb +93 -0
  198. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/features.rb +150 -0
  199. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/logging.rb +91 -0
  200. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/misc.rb +663 -0
  201. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/query.rb +436 -0
  202. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/schema_generator.rb +720 -0
  203. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/schema_methods.rb +1157 -0
  204. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database/transactions.rb +552 -0
  205. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/database.rb +37 -0
  206. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/actions.rb +1412 -0
  207. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/dataset_module.rb +46 -0
  208. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
  209. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/features.rb +284 -0
  210. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/graph.rb +297 -0
  211. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/misc.rb +381 -0
  212. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/placeholder_literalizer.rb +230 -0
  213. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/prepared_statements.rb +474 -0
  214. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/query.rb +1571 -0
  215. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset/sql.rb +1863 -0
  216. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/dataset.rb +60 -0
  217. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/deprecated.rb +70 -0
  218. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/exceptions.rb +130 -0
  219. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  220. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/_model_pg_row.rb +31 -0
  221. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/_pretty_table.rb +85 -0
  222. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/any_not_empty.rb +45 -0
  223. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/arbitrary_servers.rb +114 -0
  224. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/async_thread_pool.rb +446 -0
  225. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
  226. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  227. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/blank.rb +57 -0
  228. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/caller_logging.rb +80 -0
  229. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/columns_introspection.rb +88 -0
  230. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/connection_checkout_event_callback.rb +151 -0
  231. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/connection_expiration.rb +105 -0
  232. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/connection_validator.rb +133 -0
  233. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/constant_sql_override.rb +65 -0
  234. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/constraint_validations.rb +510 -0
  235. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/core_extensions.rb +222 -0
  236. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/core_refinements.rb +244 -0
  237. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/current_datetime_timestamp.rb +59 -0
  238. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/dataset_run.rb +41 -0
  239. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/dataset_source_alias.rb +95 -0
  240. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/date_arithmetic.rb +254 -0
  241. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  242. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
  243. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/duplicate_columns_handler.rb +95 -0
  244. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/empty_array_consider_nulls.rb +46 -0
  245. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/error_sql.rb +76 -0
  246. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/escaped_like.rb +100 -0
  247. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/eval_inspect.rb +185 -0
  248. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/exclude_or_null.rb +68 -0
  249. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  250. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/freeze_datasets.rb +3 -0
  251. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/from_block.rb +3 -0
  252. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/graph_each.rb +88 -0
  253. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/identifier_mangling.rb +180 -0
  254. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/implicit_subquery.rb +48 -0
  255. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/index_caching.rb +113 -0
  256. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/inflector.rb +258 -0
  257. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/integer64.rb +32 -0
  258. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/is_distinct_from.rb +141 -0
  259. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/looser_typecasting.rb +50 -0
  260. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/migration.rb +867 -0
  261. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +84 -0
  262. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/named_timezones.rb +184 -0
  263. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  264. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/null_dataset.rb +109 -0
  265. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pagination.rb +140 -0
  266. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_array.rb +556 -0
  267. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_array_ops.rb +377 -0
  268. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_auto_parameterize.rb +516 -0
  269. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb +191 -0
  270. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +194 -0
  271. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_enum.rb +199 -0
  272. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_extended_date_support.rb +261 -0
  273. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
  274. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_hstore.rb +353 -0
  275. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_hstore_ops.rb +418 -0
  276. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_inet.rb +136 -0
  277. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_inet_ops.rb +204 -0
  278. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_interval.rb +224 -0
  279. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_json.rb +644 -0
  280. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_json_ops.rb +1460 -0
  281. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_loose_count.rb +39 -0
  282. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_multirange.rb +367 -0
  283. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_range.rb +572 -0
  284. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_range_ops.rb +195 -0
  285. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_row.rb +585 -0
  286. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_row_ops.rb +217 -0
  287. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_schema_caching.rb +90 -0
  288. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_static_cache_updater.rb +144 -0
  289. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pg_timestamptz.rb +52 -0
  290. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/pretty_table.rb +40 -0
  291. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/provenance.rb +108 -0
  292. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/query.rb +85 -0
  293. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/query_blocker.rb +172 -0
  294. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/round_timestamps.rb +49 -0
  295. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  296. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/s.rb +60 -0
  297. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/schema_caching.rb +103 -0
  298. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/schema_dumper.rb +550 -0
  299. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/select_remove.rb +52 -0
  300. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  301. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/server_block.rb +179 -0
  302. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/server_logging.rb +61 -0
  303. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/set_literalizer.rb +39 -0
  304. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/split_array_nil.rb +80 -0
  305. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/sql_comments.rb +203 -0
  306. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/sql_expr.rb +23 -0
  307. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  308. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/sqlite_json_ops.rb +313 -0
  309. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/stdio_logger.rb +48 -0
  310. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/string_agg.rb +194 -0
  311. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/string_date_time.rb +48 -0
  312. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/symbol_aref.rb +55 -0
  313. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  314. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/symbol_as.rb +23 -0
  315. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  316. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/synchronize_sql.rb +45 -0
  317. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/temporarily_release_connection.rb +178 -0
  318. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/thread_local_timezones.rb +59 -0
  319. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/to_dot.rb +169 -0
  320. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
  321. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/extensions/virtual_row_method_block.rb +45 -0
  322. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/associations.rb +4066 -0
  323. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/base.rb +2360 -0
  324. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/dataset_module.rb +36 -0
  325. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/default_inflections.rb +47 -0
  326. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/errors.rb +67 -0
  327. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/exceptions.rb +67 -0
  328. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/inflections.rb +151 -0
  329. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model/plugins.rb +165 -0
  330. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/model.rb +85 -0
  331. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/accessed_columns.rb +63 -0
  332. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/active_model.rb +124 -0
  333. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/after_initialize.rb +39 -0
  334. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/association_dependencies.rb +106 -0
  335. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  336. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  337. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/association_pks.rb +316 -0
  338. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/association_proxies.rb +131 -0
  339. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/async_thread_pool.rb +39 -0
  340. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  341. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/auto_validations.rb +302 -0
  342. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  343. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/before_after_save.rb +8 -0
  344. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/blacklist_security.rb +104 -0
  345. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/boolean_readers.rb +59 -0
  346. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/boolean_subsets.rb +64 -0
  347. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/caching.rb +164 -0
  348. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/class_table_inheritance.rb +439 -0
  349. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/class_table_inheritance_constraint_validations.rb +82 -0
  350. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/column_conflicts.rb +108 -0
  351. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/column_encryption.rb +749 -0
  352. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/column_select.rb +61 -0
  353. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/columns_updated.rb +42 -0
  354. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/composition.rb +205 -0
  355. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  356. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/constraint_validations.rb +259 -0
  357. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/csv_serializer.rb +196 -0
  358. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/dataset_associations.rb +152 -0
  359. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/def_dataset_method.rb +90 -0
  360. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/defaults_setter.rb +158 -0
  361. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/delay_add_association.rb +53 -0
  362. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/deprecated_associations.rb +151 -0
  363. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/detect_unnecessary_association_options.rb +164 -0
  364. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/dirty.rb +276 -0
  365. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/eager_each.rb +88 -0
  366. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  367. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  368. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/enum.rb +124 -0
  369. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/error_splitter.rb +61 -0
  370. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/finder.rb +248 -0
  371. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/forbid_lazy_load.rb +229 -0
  372. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/force_encoding.rb +78 -0
  373. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/hook_class_methods.rb +110 -0
  374. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/input_transformer.rb +89 -0
  375. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/insert_conflict.rb +76 -0
  376. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/insert_returning_select.rb +81 -0
  377. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/inspect_pk.rb +44 -0
  378. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/instance_filters.rb +138 -0
  379. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/instance_hooks.rb +115 -0
  380. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/instance_specific_default.rb +113 -0
  381. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/inverted_subsets.rb +60 -0
  382. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/json_serializer.rb +445 -0
  383. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/lazy_attributes.rb +126 -0
  384. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/list.rb +208 -0
  385. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/many_through_many.rb +437 -0
  386. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/modification_detection.rb +102 -0
  387. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/mssql_optimistic_locking.rb +65 -0
  388. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/nested_attributes.rb +340 -0
  389. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/optimistic_locking.rb +54 -0
  390. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
  391. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/paged_operations.rb +184 -0
  392. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_array_associations.rb +580 -0
  393. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_auto_constraint_validations.rb +361 -0
  394. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_auto_validate_enums.rb +88 -0
  395. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_eager_any_typed_array.rb +95 -0
  396. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_row.rb +79 -0
  397. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
  398. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/prepared_statements.rb +196 -0
  399. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  400. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
  401. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/rcte_tree.rb +343 -0
  402. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/require_valid_schema.rb +67 -0
  403. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/serialization.rb +242 -0
  404. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/serialization_modification_detection.rb +87 -0
  405. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/sharding.rb +126 -0
  406. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/single_statement_dataset_destroy.rb +49 -0
  407. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/single_table_inheritance.rb +271 -0
  408. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/singular_table_names.rb +33 -0
  409. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/skip_create_refresh.rb +37 -0
  410. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  411. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/split_values.rb +81 -0
  412. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/sql_comments.rb +194 -0
  413. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/static_cache.rb +315 -0
  414. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/static_cache_cache.rb +94 -0
  415. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/string_stripper.rb +59 -0
  416. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/subclasses.rb +96 -0
  417. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/subset_conditions.rb +128 -0
  418. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/subset_static_cache.rb +278 -0
  419. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/table_select.rb +50 -0
  420. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/tactical_eager_loading.rb +216 -0
  421. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/throw_failures.rb +110 -0
  422. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/timestamps.rb +109 -0
  423. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/touch.rb +153 -0
  424. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/tree.rb +188 -0
  425. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/typecast_on_load.rb +90 -0
  426. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/unlimited_update.rb +27 -0
  427. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/unused_associations.rb +529 -0
  428. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/update_or_create.rb +64 -0
  429. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/update_primary_key.rb +72 -0
  430. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/update_refresh.rb +88 -0
  431. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/uuid.rb +70 -0
  432. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/validate_associated.rb +85 -0
  433. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/validation_class_methods.rb +460 -0
  434. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/validation_contexts.rb +49 -0
  435. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/validation_helpers.rb +351 -0
  436. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
  437. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/whitelist_security.rb +122 -0
  438. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/plugins/xml_serializer.rb +411 -0
  439. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/sql.rb +2061 -0
  440. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/timezones.rb +254 -0
  441. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel/version.rb +25 -0
  442. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sequel-5.102.0/lib/sequel.rb +3 -0
  443. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/CHANGELOG.md +1014 -0
  444. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/CONTRIBUTING.md +60 -0
  445. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/FAQ.md +399 -0
  446. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/INSTALLATION.md +267 -0
  447. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/LICENSE +23 -0
  448. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/README.md +198 -0
  449. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/dependencies.yml +13 -0
  450. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/aggregator.c +270 -0
  451. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/aggregator.h +10 -0
  452. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/backup.c +190 -0
  453. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/backup.h +15 -0
  454. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/database.c +1006 -0
  455. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/database.h +28 -0
  456. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/exception.c +122 -0
  457. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/exception.h +12 -0
  458. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/extconf.rb +297 -0
  459. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/sqlite3.c +225 -0
  460. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/sqlite3_ruby.h +48 -0
  461. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/statement.c +739 -0
  462. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/statement.h +17 -0
  463. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/ext/sqlite3/timespec.h +20 -0
  464. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/3.2/sqlite3_native.so +0 -0
  465. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/3.3/sqlite3_native.so +0 -0
  466. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/3.4/sqlite3_native.so +0 -0
  467. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/4.0/sqlite3_native.so +0 -0
  468. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/constants.rb +198 -0
  469. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/database.rb +798 -0
  470. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/errors.rb +88 -0
  471. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/fork_safety.rb +66 -0
  472. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/pragmas.rb +648 -0
  473. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/resultset.rb +96 -0
  474. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/statement.rb +190 -0
  475. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/value.rb +54 -0
  476. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/version.rb +4 -0
  477. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3/version_info.rb +17 -0
  478. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/sqlite3-2.9.1-x64-mingw-ucrt/lib/sqlite3.rb +19 -0
  479. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile +10 -0
  480. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt +22 -0
  481. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md +63 -0
  482. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile +10 -0
  483. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/accesslog.rb +157 -0
  484. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb +313 -0
  485. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb +36 -0
  486. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb +158 -0
  487. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb +172 -0
  488. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/htmlutils.rb +30 -0
  489. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/authenticator.rb +117 -0
  490. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/basicauth.rb +116 -0
  491. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/digestauth.rb +395 -0
  492. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htdigest.rb +132 -0
  493. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htgroup.rb +97 -0
  494. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb +158 -0
  495. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/userdb.rb +53 -0
  496. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth.rb +96 -0
  497. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpproxy.rb +354 -0
  498. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httprequest.rb +668 -0
  499. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpresponse.rb +588 -0
  500. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb +152 -0
  501. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpserver.rb +294 -0
  502. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/abstract.rb +152 -0
  503. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  504. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgihandler.rb +126 -0
  505. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/erbhandler.rb +88 -0
  506. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/filehandler.rb +552 -0
  507. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/prochandler.rb +48 -0
  508. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet.rb +23 -0
  509. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpstatus.rb +194 -0
  510. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httputils.rb +543 -0
  511. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpversion.rb +76 -0
  512. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb +156 -0
  513. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb +380 -0
  514. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb +219 -0
  515. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb +265 -0
  516. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/version.rb +18 -0
  517. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb +232 -0
  518. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs +24 -0
  519. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs +92 -0
  520. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs +18 -0
  521. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs +17 -0
  522. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs +37 -0
  523. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs +5 -0
  524. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/authenticator.rbs +55 -0
  525. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/basicauth.rbs +29 -0
  526. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/digestauth.rbs +85 -0
  527. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htdigest.rbs +31 -0
  528. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htgroup.rbs +21 -0
  529. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs +31 -0
  530. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/userdb.rbs +13 -0
  531. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs +13 -0
  532. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs +61 -0
  533. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs +167 -0
  534. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs +117 -0
  535. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs +49 -0
  536. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs +71 -0
  537. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/abstract.rbs +36 -0
  538. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgi_runner.rbs +3 -0
  539. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgihandler.rbs +23 -0
  540. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/erbhandler.rbs +17 -0
  541. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/filehandler.rbs +76 -0
  542. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/prochandler.rbs +21 -0
  543. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs +4 -0
  544. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs +255 -0
  545. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httputils.rbs +116 -0
  546. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs +17 -0
  547. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs +93 -0
  548. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/manifest.yaml +8 -0
  549. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs +57 -0
  550. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs +19 -0
  551. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs +122 -0
  552. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs +3 -0
  553. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec +105 -0
  554. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/bigdecimal-4.0.1.gemspec +25 -0
  555. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/rack-3.2.5.gemspec +31 -0
  556. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/rackup-2.3.1.gemspec +26 -0
  557. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/sequel-5.102.0.gemspec +36 -0
  558. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/sqlite3-2.9.1-x64-mingw-ucrt.gemspec +25 -0
  559. data/examples/demo_crud/vendor/bundle/ruby/3.4.0/specifications/webrick-1.9.2.gemspec +22 -0
  560. data/lib/serrano/application.rb +36 -0
  561. data/lib/serrano/cli/base.rb +92 -0
  562. data/lib/serrano/cli/generate.rb +285 -0
  563. data/lib/serrano/cli/templates/controller.rb.tt +92 -0
  564. data/lib/serrano/cli/templates/entity.rb.tt +43 -0
  565. data/lib/serrano/cli/templates/entity_validatable.rb.tt +136 -0
  566. data/lib/serrano/cli/templates/migration.rb.tt +19 -0
  567. data/lib/serrano/cli/templates/new_default_config.ru.tt +6 -0
  568. data/lib/serrano/cli/templates/new_default_db.rb.tt +3 -0
  569. data/lib/serrano/cli/templates/new_default_gemfile.tt +6 -0
  570. data/lib/serrano/cli/templates/new_minimal_config.ru.tt +5 -0
  571. data/lib/serrano/cli/templates/new_minimal_gemfile.tt +4 -0
  572. data/lib/serrano/cli/templates/new_project_config.ru.tt +8 -0
  573. data/lib/serrano/cli/templates/new_project_db.rb.tt +3 -0
  574. data/lib/serrano/cli/templates/new_project_gemfile.tt +8 -0
  575. data/lib/serrano/cli/templates/repository.rb.tt +42 -0
  576. data/lib/serrano/cli/templates/service_create.rb.tt +40 -0
  577. data/lib/serrano/cli/templates/service_destroy.rb.tt +20 -0
  578. data/lib/serrano/cli/templates/service_generic.rb.tt +15 -0
  579. data/lib/serrano/cli/templates/service_index.rb.tt +17 -0
  580. data/lib/serrano/cli/templates/service_show.rb.tt +20 -0
  581. data/lib/serrano/cli/templates/service_update.rb.tt +41 -0
  582. data/lib/serrano/dispatcher.rb +53 -0
  583. data/lib/serrano/request.rb +78 -0
  584. data/lib/serrano/response.rb +33 -0
  585. data/lib/serrano/router.rb +80 -0
  586. data/lib/serrano/version.rb +5 -0
  587. data/lib/serrano.rb +11 -0
  588. metadata +768 -0
@@ -0,0 +1,2360 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ class Model
5
+ # SEQUEL6: Remove Enumerable here, and send all Enumerable methods to dataset
6
+ # by default, with a plugin for the current behavior.
7
+ extend Enumerable
8
+ extend Inflections
9
+
10
+ # Class methods for Sequel::Model that implement basic model functionality.
11
+ #
12
+ # * All of the following methods have class methods created that send the method
13
+ # to the model's dataset: all, any?, as_hash, as_set, avg, count, cross_join, distinct, each,
14
+ # each_server, empty?, except, exclude, exclude_having, fetch_rows,
15
+ # filter, first, first!, for_update, from, from_self, full_join, full_outer_join,
16
+ # get, graph, grep, group, group_and_count, group_append, group_by, having, import,
17
+ # inner_join, insert, intersect, invert, join, join_table, last, left_join,
18
+ # left_outer_join, limit, lock_style, map, max, min, multi_insert, naked, natural_full_join,
19
+ # natural_join, natural_left_join, natural_right_join, offset, order, order_append, order_by,
20
+ # order_more, order_prepend, paged_each, qualify, reverse, reverse_order, right_join,
21
+ # right_outer_join, select, select_all, select_append, select_group, select_hash,
22
+ # select_hash_groups, select_map, select_more, select_order_map, select_prepend, select_set, server,
23
+ # single_record, single_record!, single_value, single_value!, sum, to_hash, to_hash_groups,
24
+ # truncate, unfiltered, ungraphed, ungrouped, union, unlimited, unordered, where, where_all,
25
+ # where_each, where_single_value, with, with_recursive, with_sql
26
+ module ClassMethods
27
+ # Whether to cache the anonymous models created by Sequel::Model(), true by default. This is
28
+ # required for reloading them correctly (avoiding the superclass mismatch).
29
+ attr_accessor :cache_anonymous_models
30
+
31
+ # Array of modules that extend this model's dataset. Stored
32
+ # so that if the model's dataset is changed, it will be extended
33
+ # with all of these modules.
34
+ attr_reader :dataset_method_modules
35
+
36
+ # The Module subclass to use for dataset_module blocks.
37
+ attr_reader :dataset_module_class
38
+
39
+ # The default options to use for Model#set_fields. These are merged with
40
+ # the options given to set_fields.
41
+ attr_accessor :default_set_fields_options
42
+
43
+ # SQL string fragment used for faster DELETE statement creation when deleting/destroying
44
+ # model instances, or nil if the optimization should not be used. For internal use only.
45
+ attr_reader :fast_instance_delete_sql
46
+
47
+ # SQL string fragment used for faster lookups by primary key, or nil if the optimization
48
+ # should not be used. For internal use only.
49
+ attr_reader :fast_pk_lookup_sql
50
+
51
+ # The dataset that instance datasets (#this) are based on. Generally a naked version of
52
+ # the model's dataset limited to one row. For internal use only.
53
+ attr_reader :instance_dataset
54
+
55
+ # Array of plugin modules loaded by this class
56
+ #
57
+ # Sequel::Model.plugins
58
+ # # => [Sequel::Model, Sequel::Model::Associations]
59
+ attr_reader :plugins
60
+
61
+ # The primary key for the class. Sequel can determine this automatically for
62
+ # many databases, but not all, so you may need to set it manually. If not
63
+ # determined automatically, the default is :id.
64
+ attr_reader :primary_key
65
+
66
+ # Whether to raise an error instead of returning nil on a failure
67
+ # to save/create/save_changes/update/destroy due to a validation failure or
68
+ # a before_* hook returning false (default: true).
69
+ attr_accessor :raise_on_save_failure
70
+
71
+ # Whether to raise an error when unable to typecast data for a column
72
+ # (default: false). This should be set to true if you want to have model
73
+ # setter methods raise errors if the argument cannot be typecast properly.
74
+ attr_accessor :raise_on_typecast_failure
75
+
76
+ # Whether to raise an error if an UPDATE or DELETE query related to
77
+ # a model instance does not modify exactly 1 row. If set to false,
78
+ # Sequel will not check the number of rows modified (default: true).
79
+ attr_accessor :require_modification
80
+
81
+ # If true (the default), requires that all models have valid tables,
82
+ # raising exceptions if creating a model without a valid table backing it.
83
+ # Setting this to false will allow the creation of model classes where the
84
+ # underlying table doesn't exist.
85
+ attr_accessor :require_valid_table
86
+
87
+ # Should be the literal primary key column name if this Model's table has a simple primary key, or
88
+ # nil if the model has a compound primary key or no primary key.
89
+ attr_reader :simple_pk
90
+
91
+ # Should be the literal table name if this Model's dataset is a simple table (no select, order, join, etc.),
92
+ # or nil otherwise. This and simple_pk are used for an optimization in Model[].
93
+ attr_reader :simple_table
94
+
95
+ # Whether mass assigning via .create/.new/#set/#update should raise an error
96
+ # if an invalid key is used. A key is invalid if no setter method exists
97
+ # for that key or the access to the setter method is restricted (e.g. due to it
98
+ # being a primary key field). If set to false, silently skip
99
+ # any key where the setter method doesn't exist or access to it is restricted.
100
+ attr_accessor :strict_param_setting
101
+
102
+ # Whether to typecast the empty string ('') to nil for columns that
103
+ # are not string or blob. In most cases the empty string would be the
104
+ # way to specify a NULL SQL value in string form (nil.to_s == ''),
105
+ # and an empty string would not usually be typecast correctly for other
106
+ # types, so the default is true.
107
+ attr_accessor :typecast_empty_string_to_nil
108
+
109
+ # Whether to typecast attribute values on assignment (default: true).
110
+ # If set to false, no typecasting is done, so it will be left up to the
111
+ # database to typecast the value correctly.
112
+ attr_accessor :typecast_on_assignment
113
+
114
+ # Whether to use a transaction by default when saving/deleting records (default: true).
115
+ # If you are sending database queries in before_* or after_* hooks, you shouldn't change
116
+ # the default setting without a good reason.
117
+ attr_accessor :use_transactions
118
+
119
+ # Define a Model method on the given module that calls the Model
120
+ # method on the receiver. This is how the Sequel::Model() method is
121
+ # defined, and allows you to define Model() methods on other modules,
122
+ # making it easier to have custom model settings for all models under
123
+ # a namespace. Example:
124
+ #
125
+ # module Foo
126
+ # Model = Class.new(Sequel::Model)
127
+ # Model.def_Model(self)
128
+ # DB = Model.db = Sequel.connect(ENV['FOO_DATABASE_URL'])
129
+ # Model.plugin :prepared_statements
130
+ #
131
+ # class Bar < Model
132
+ # # Uses Foo::DB[:bars]
133
+ # end
134
+ #
135
+ # class Baz < Model(:my_baz)
136
+ # # Uses Foo::DB[:my_baz]
137
+ # end
138
+ # end
139
+ def def_Model(mod)
140
+ model = self
141
+ mod.define_singleton_method(:Model) do |source|
142
+ model.Model(source)
143
+ end
144
+ end
145
+
146
+ # Lets you create a Model subclass with its dataset already set.
147
+ # +source+ should be an instance of one of the following classes:
148
+ #
149
+ # Database :: Sets the database for this model to +source+.
150
+ # Generally only useful when subclassing directly
151
+ # from the returned class, where the name of the
152
+ # subclass sets the table name (which is combined
153
+ # with the +Database+ in +source+ to create the
154
+ # dataset to use)
155
+ # Dataset :: Sets the dataset for this model to +source+.
156
+ # other :: Sets the table name for this model to +source+. The
157
+ # class will use the default database for model
158
+ # classes in order to create the dataset.
159
+ #
160
+ # The purpose of this method is to set the dataset/database automatically
161
+ # for a model class, if the table name doesn't match the default table
162
+ # name that Sequel would use.
163
+ #
164
+ # When creating subclasses of Sequel::Model itself, this method is usually
165
+ # called on Sequel itself, using <tt>Sequel::Model(:something)</tt>.
166
+ #
167
+ # # Using a symbol
168
+ # class Comment < Sequel::Model(:something)
169
+ # table_name # => :something
170
+ # end
171
+ #
172
+ # # Using a dataset
173
+ # class Comment < Sequel::Model(DB1[:something])
174
+ # dataset # => DB1[:something]
175
+ # end
176
+ #
177
+ # # Using a database
178
+ # class Comment < Sequel::Model(DB1)
179
+ # dataset # => DB1[:comments]
180
+ # end
181
+ def Model(source)
182
+ if cache_anonymous_models
183
+ cache = Sequel.synchronize{@Model_cache ||= {}}
184
+ if klass = Sequel.synchronize{cache[source]}
185
+ return klass
186
+ end
187
+ end
188
+
189
+ klass = Sequel.set_temp_name(Class.new(self)){"Sequel::_Model(#{source.inspect})"}
190
+
191
+ if source.is_a?(::Sequel::Database)
192
+ klass.db = source
193
+ else
194
+ klass.set_dataset(source)
195
+ end
196
+
197
+ if cache_anonymous_models
198
+ Sequel.synchronize{cache[source] = klass}
199
+ end
200
+
201
+ klass
202
+ end
203
+
204
+ # Returns the first record from the database matching the conditions.
205
+ # If a hash is given, it is used as the conditions. If another
206
+ # object is given, it finds the first record whose primary key(s) match
207
+ # the given argument(s). If no object is returned by the dataset, returns nil.
208
+ #
209
+ # Artist[1] # SELECT * FROM artists WHERE id = 1
210
+ # # => #<Artist {:id=>1, ...}>
211
+ #
212
+ # Artist[name: 'Bob'] # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
213
+ # # => #<Artist {:name=>'Bob', ...}>
214
+ def [](*args)
215
+ args = args.first if args.size <= 1
216
+ args.is_a?(Hash) ? first(args) : (primary_key_lookup(args) unless args.nil?)
217
+ end
218
+
219
+ # Initializes a model instance as an existing record. This constructor is
220
+ # used by Sequel to initialize model instances when fetching records.
221
+ # Requires that values be a hash where all keys are symbols. It
222
+ # probably should not be used by external code.
223
+ def call(values)
224
+ o = allocate
225
+ o.instance_variable_set(:@values, values)
226
+ o
227
+ end
228
+
229
+ # Clear the setter_methods cache
230
+ def clear_setter_methods_cache
231
+ @setter_methods = nil unless frozen?
232
+ end
233
+
234
+ # Returns the columns in the result set in their original order.
235
+ # Generally, this will use the columns determined via the database
236
+ # schema, but in certain cases (e.g. models that are based on a joined
237
+ # dataset) it will use <tt>Dataset#columns</tt> to find the columns.
238
+ #
239
+ # Artist.columns
240
+ # # => [:id, :name]
241
+ def columns
242
+ return @columns if @columns
243
+ return nil if frozen?
244
+ set_columns(dataset.naked.columns)
245
+ end
246
+
247
+ # Creates instance using new with the given values and block, and saves it.
248
+ #
249
+ # Artist.create(name: 'Bob')
250
+ # # INSERT INTO artists (name) VALUES ('Bob')
251
+ #
252
+ # Artist.create do |a|
253
+ # a.name = 'Jim'
254
+ # end # INSERT INTO artists (name) VALUES ('Jim')
255
+ def create(values = OPTS, &block)
256
+ new(values, &block).save
257
+ end
258
+
259
+ # Returns the dataset associated with the Model class. Raises
260
+ # an +Error+ if there is no associated dataset for this class.
261
+ # In most cases, you don't need to call this directly, as Model
262
+ # proxies many dataset methods to the underlying dataset.
263
+ #
264
+ # Artist.dataset.all # SELECT * FROM artists
265
+ def dataset
266
+ @dataset || raise(Error, "No dataset associated with #{self}")
267
+ end
268
+
269
+ # Alias of set_dataset
270
+ def dataset=(ds)
271
+ set_dataset(ds)
272
+ end
273
+
274
+ # Extend the dataset with a module, similar to adding
275
+ # a plugin with the methods defined in DatasetMethods.
276
+ # This is the recommended way to add methods to model datasets.
277
+ #
278
+ # If given an argument, it should be a module, and is used to extend
279
+ # the underlying dataset. Otherwise an anonymous module is created, and
280
+ # if a block is given, it is module_evaled, allowing you do define
281
+ # dataset methods directly using the standard ruby def syntax.
282
+ # Returns the module given or the anonymous module created.
283
+ #
284
+ # # Usage with existing module
285
+ # Album.dataset_module Sequel::ColumnsIntrospection
286
+ #
287
+ # # Usage with anonymous module
288
+ # Album.dataset_module do
289
+ # def foo
290
+ # :bar
291
+ # end
292
+ # end
293
+ # Album.dataset.foo
294
+ # # => :bar
295
+ # Album.foo
296
+ # # => :bar
297
+ #
298
+ # Any anonymous modules created are actually instances of Sequel::Model::DatasetModule
299
+ # (a Module subclass), which allows you to call the subset method on them, which
300
+ # defines a dataset method that adds a filter. There are also a number of other
301
+ # methods with the same names as the dataset methods, which can use to define
302
+ # named dataset methods:
303
+ #
304
+ # Album.dataset_module do
305
+ # where(:released, Sequel[:release_date] <= Sequel::CURRENT_DATE)
306
+ # order :by_release_date, :release_date
307
+ # select :for_select_options, :id, :name, :release_date
308
+ # end
309
+ # Album.released.sql
310
+ # # => "SELECT * FROM artists WHERE (release_date <= CURRENT_DATE)"
311
+ # Album.by_release_date.sql
312
+ # # => "SELECT * FROM artists ORDER BY release_date"
313
+ # Album.for_select_options.sql
314
+ # # => "SELECT id, name, release_date FROM artists"
315
+ # Album.released.by_release_date.for_select_options.sql
316
+ # # => "SELECT id, name, release_date FROM artists WHERE (release_date <= CURRENT_DATE) ORDER BY release_date"
317
+ #
318
+ # The following methods are supported: distinct, eager, exclude, exclude_having, grep, group, group_and_count,
319
+ # group_append, having, limit, offset, order, order_append, order_prepend, select, select_all,
320
+ # select_append, select_group, where, and server.
321
+ #
322
+ # The advantage of using these DatasetModule methods to define your dataset
323
+ # methods is that they can take advantage of dataset caching to improve
324
+ # performance.
325
+ #
326
+ # Any public methods in the dataset module will have class methods created that
327
+ # call the method on the dataset, assuming that the class method is not already
328
+ # defined.
329
+ def dataset_module(mod = nil, &block)
330
+ if mod
331
+ raise Error, "can't provide both argument and block to Model.dataset_module" if block
332
+ dataset_extend(mod)
333
+ mod
334
+ else
335
+ @dataset_module ||= dataset_module_class.new(self)
336
+ @dataset_module.module_eval(&block) if block
337
+ dataset_extend(@dataset_module)
338
+ @dataset_module
339
+ end
340
+ end
341
+
342
+ # Returns the database associated with the Model class.
343
+ # If this model doesn't have a database associated with it,
344
+ # assumes the superclass's database, or the first object in
345
+ # Sequel::DATABASES. If no Sequel::Database object has
346
+ # been created, raises an error.
347
+ #
348
+ # Artist.db.transaction do # BEGIN
349
+ # Artist.create(name: 'Bob')
350
+ # # INSERT INTO artists (name) VALUES ('Bob')
351
+ # end # COMMIT
352
+ def db
353
+ return @db if @db
354
+ @db = self == Model ? Sequel.synchronize{DATABASES.first} : superclass.db
355
+ raise(Error, "No database associated with #{self}: have you called Sequel.connect or #{self}.db= ?") unless @db
356
+ @db
357
+ end
358
+
359
+ # Sets the database associated with the Model class.
360
+ # Should only be used if the Model class currently does not
361
+ # have a dataset defined.
362
+ #
363
+ # This can be used directly on Sequel::Model to set the default database to be used
364
+ # by subclasses, or to override the database used for specific models:
365
+ #
366
+ # Sequel::Model.db = DB1
367
+ # Artist = Class.new(Sequel::Model)
368
+ # Artist.db = DB2
369
+ #
370
+ # Note that you should not use this to change the model's database
371
+ # at runtime. If you have that need, you should look into Sequel's
372
+ # sharding support, or consider using separate model classes per Database.
373
+ def db=(db)
374
+ raise Error, "Cannot use Sequel::Model.db= on model with existing dataset. Use Sequel::Model.dataset= instead." if @dataset
375
+ @db = db
376
+ end
377
+
378
+ # Returns the cached schema information if available or gets it
379
+ # from the database. This is a hash where keys are column symbols
380
+ # and values are hashes of information related to the column. See
381
+ # <tt>Database#schema</tt>.
382
+ #
383
+ # Artist.db_schema
384
+ # # {:id=>{:type=>:integer, :primary_key=>true, ...},
385
+ # # :name=>{:type=>:string, :primary_key=>false, ...}}
386
+ def db_schema
387
+ return @db_schema if @db_schema
388
+ return nil if frozen?
389
+ @db_schema = get_db_schema
390
+ end
391
+
392
+ # Create a column alias, where the column methods have one name, but the underlying storage uses a
393
+ # different name.
394
+ def def_column_alias(meth, column)
395
+ clear_setter_methods_cache
396
+ overridable_methods_module.module_eval do
397
+ define_method(meth){self[column]}
398
+ define_method("#{meth}="){|v| self[column] = v}
399
+ end
400
+ end
401
+
402
+ # Finds a single record according to the supplied filter.
403
+ # You are encouraged to use Model[] or Model.first instead of this method.
404
+ #
405
+ # Artist.find(name: 'Bob')
406
+ # # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
407
+ #
408
+ # Artist.find{name > 'M'}
409
+ # # SELECT * FROM artists WHERE (name > 'M') LIMIT 1
410
+ def find(*args, &block)
411
+ first(*args, &block)
412
+ end
413
+
414
+ # Like +find+ but invokes create with given conditions when record does not
415
+ # exist. Unlike +find+ in that the block used in this method is not passed
416
+ # to +find+, but instead is passed to +create+ only if +find+ does not
417
+ # return an object.
418
+ #
419
+ # Artist.find_or_create(name: 'Bob')
420
+ # # SELECT * FROM artists WHERE (name = 'Bob') LIMIT 1
421
+ # # INSERT INTO artists (name) VALUES ('Bob')
422
+ #
423
+ # Artist.find_or_create(name: 'Jim'){|a| a.hometown = 'Sactown'}
424
+ # # SELECT * FROM artists WHERE (name = 'Jim') LIMIT 1
425
+ # # INSERT INTO artists (name, hometown) VALUES ('Jim', 'Sactown')
426
+ def find_or_create(cond, &block)
427
+ find(cond) || create(cond, &block)
428
+ end
429
+
430
+ # Freeze a model class, disallowing any further changes to it.
431
+ def freeze
432
+ return self if frozen?
433
+ dataset_module.freeze
434
+ overridable_methods_module.freeze
435
+
436
+ if @dataset
437
+ db_schema.freeze.each_value(&:freeze)
438
+ columns.freeze
439
+ setter_methods.freeze
440
+ else
441
+ @setter_methods = [].freeze
442
+ end
443
+
444
+ @dataset_method_modules.freeze
445
+ @default_set_fields_options.freeze
446
+ @plugins.freeze
447
+
448
+ super
449
+ end
450
+
451
+ # Whether the model has a dataset. True for most model classes,
452
+ # but can be false if the model class is an abstract model class
453
+ # designed for subclassing, such as Sequel::Model itself.
454
+ def has_dataset?
455
+ !@dataset.nil?
456
+ end
457
+
458
+ # Clear the setter_methods cache when a module is included, as it
459
+ # may contain setter methods.
460
+ def include(*mods)
461
+ clear_setter_methods_cache
462
+ super
463
+ end
464
+
465
+ # Returns the implicit table name for the model class, which is the demodulized,
466
+ # underscored, pluralized name of the class.
467
+ #
468
+ # Artist.implicit_table_name # => :artists
469
+ # Foo::ArtistAlias.implicit_table_name # => :artist_aliases
470
+ def implicit_table_name
471
+ pluralize(underscore(demodulize(name))).to_sym
472
+ end
473
+
474
+ # Calls #call with the values hash.
475
+ def load(values)
476
+ call(values)
477
+ end
478
+
479
+ # Mark the model as not having a primary key. Not having a primary key
480
+ # can cause issues, among which is that you won't be able to update records.
481
+ #
482
+ # Artist.primary_key # => :id
483
+ # Artist.no_primary_key
484
+ # Artist.primary_key # => nil
485
+ def no_primary_key
486
+ clear_setter_methods_cache
487
+ self.simple_pk = @primary_key = nil
488
+ end
489
+
490
+ # Loads a plugin for use with the model class, passing optional arguments
491
+ # to the plugin. If the plugin is a module, load it directly. Otherwise,
492
+ # require the plugin from sequel/plugins/#{plugin} and then attempt to load
493
+ # the module using a the camelized plugin name under Sequel::Plugins.
494
+ def plugin(plugin, *args, &block)
495
+ m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
496
+
497
+ if !m.respond_to?(:apply) && !m.respond_to?(:configure) && (!args.empty? || block)
498
+ Deprecation.deprecate("Plugin #{plugin} accepts no arguments or block, and passing arguments/block to it", "Remove arguments and block when loading the plugin")
499
+ end
500
+
501
+ unless @plugins.include?(m)
502
+ @plugins << m
503
+ m.apply(self, *args, &block) if m.respond_to?(:apply)
504
+ extend(m::ClassMethods) if m.const_defined?(:ClassMethods, false)
505
+ include(m::InstanceMethods) if m.const_defined?(:InstanceMethods, false)
506
+ if m.const_defined?(:DatasetMethods, false)
507
+ dataset_extend(m::DatasetMethods, :create_class_methods=>false)
508
+ end
509
+ end
510
+
511
+ m.configure(self, *args, &block) if m.respond_to?(:configure)
512
+ end
513
+ # :nocov:
514
+ ruby2_keywords(:plugin) if respond_to?(:ruby2_keywords, true)
515
+ # :nocov:
516
+
517
+ # Returns primary key attribute hash. If using a composite primary key
518
+ # value such be an array with values for each primary key in the correct
519
+ # order. For a standard primary key, value should be an object with a
520
+ # compatible type for the key. If the model does not have a primary key,
521
+ # raises an +Error+.
522
+ #
523
+ # Artist.primary_key_hash(1) # => {:id=>1}
524
+ # Artist.primary_key_hash([1, 2]) # => {:id1=>1, :id2=>2}
525
+ def primary_key_hash(value)
526
+ case key = @primary_key
527
+ when Symbol
528
+ {key => value}
529
+ when Array
530
+ hash = {}
531
+ key.zip(Array(value)){|k,v| hash[k] = v}
532
+ hash
533
+ else
534
+ raise(Error, "#{self} does not have a primary key")
535
+ end
536
+ end
537
+
538
+ # Return a qualified identifier or array of qualified identifiers for
539
+ # the model's primary key. Uses the given qualifier if provided, or
540
+ # the table_name otherwise. If the model does not have a primary key,
541
+ # raises an +Error+.
542
+ #
543
+ # Artist.order(Artist.qualified_primary_key)
544
+ # # SELECT * FROM artists ORDER BY artists.id
545
+ def qualified_primary_key(qualifier=table_name)
546
+ case key = @primary_key
547
+ when Symbol
548
+ SQL::QualifiedIdentifier.new(qualifier, key)
549
+ when Array
550
+ key.map{|k| SQL::QualifiedIdentifier.new(qualifier, k)}
551
+ else
552
+ raise(Error, "#{self} does not have a primary key")
553
+ end
554
+ end
555
+
556
+ # Return a hash where the keys are qualified column references. Uses the given
557
+ # qualifier if provided, or the table_name otherwise. This is useful if you
558
+ # plan to join other tables to this table and you want the column references
559
+ # to be qualified. If the model does not have a primary key, raises an +Error+.
560
+ #
561
+ # Artist.where(Artist.qualified_primary_key_hash(1))
562
+ # # SELECT * FROM artists WHERE (artists.id = 1)
563
+ def qualified_primary_key_hash(value, qualifier=table_name)
564
+ case key = @primary_key
565
+ when Symbol
566
+ {SQL::QualifiedIdentifier.new(qualifier, key) => value}
567
+ when Array
568
+ hash = {}
569
+ key.zip(Array(value)){|k,v| hash[SQL::QualifiedIdentifier.new(qualifier, k)] = v}
570
+ hash
571
+ else
572
+ raise(Error, "#{self} does not have a primary key")
573
+ end
574
+ end
575
+
576
+ # Restrict the setting of the primary key(s) when using mass assignment (e.g. +set+). Because
577
+ # this is the default, this only make sense to use in a subclass where the
578
+ # parent class has used +unrestrict_primary_key+.
579
+ def restrict_primary_key
580
+ clear_setter_methods_cache
581
+ @restrict_primary_key = true
582
+ end
583
+
584
+ # Whether or not setting the primary key(s) when using mass assignment (e.g. +set+) is
585
+ # restricted, true by default.
586
+ def restrict_primary_key?
587
+ @restrict_primary_key
588
+ end
589
+
590
+ # Sets the dataset associated with the Model class. +ds+ can be a +Symbol+,
591
+ # +LiteralString+, <tt>SQL::Identifier</tt>, <tt>SQL::QualifiedIdentifier</tt>,
592
+ # <tt>SQL::AliasedExpression</tt>
593
+ # (all specifying a table name in the current database), or a +Dataset+.
594
+ # If a dataset is used, the model's database is changed to the database of the given
595
+ # dataset. If a dataset is not used, a dataset is created from the current
596
+ # database with the table name given. Other arguments raise an +Error+.
597
+ # Returns self.
598
+ #
599
+ # It also attempts to determine the database schema for the model,
600
+ # based on the given dataset.
601
+ #
602
+ # Note that you should not use this to change the model's dataset
603
+ # at runtime. If you have that need, you should look into Sequel's
604
+ # sharding support, or creating a separate Model class per dataset
605
+ #
606
+ # You should avoid calling this method directly if possible. Instead you should
607
+ # set the table name or dataset when creating the model class:
608
+ #
609
+ # # table name
610
+ # class Artist < Sequel::Model(:tbl_artists)
611
+ # end
612
+ #
613
+ # # dataset
614
+ # class Artist < Sequel::Model(DB[:tbl_artists])
615
+ # end
616
+ def set_dataset(ds, opts=OPTS)
617
+ inherited = opts[:inherited]
618
+ @dataset = convert_input_dataset(ds)
619
+ @require_modification = @dataset.provides_accurate_rows_matched? if require_modification.nil?
620
+ if inherited
621
+ self.simple_table = superclass.simple_table
622
+ @columns = superclass.instance_variable_get(:@columns)
623
+ @db_schema = superclass.instance_variable_get(:@db_schema)
624
+ else
625
+ @dataset = @dataset.with_extend(*@dataset_method_modules.reverse)
626
+ @db_schema = get_db_schema
627
+ end
628
+
629
+ @fast_pk_lookup_sql = @fast_instance_delete_sql = nil unless @dataset.supports_placeholder_literalizer?
630
+ reset_instance_dataset
631
+ self
632
+ end
633
+
634
+ # Sets the primary key for this model. You can use either a regular
635
+ # or a composite primary key. To not use a primary key, set to nil
636
+ # or use +no_primary_key+. On most adapters, Sequel can automatically
637
+ # determine the primary key to use, so this method is not needed often.
638
+ #
639
+ # class Person < Sequel::Model
640
+ # # regular key
641
+ # set_primary_key :person_id
642
+ # end
643
+ #
644
+ # class Tagging < Sequel::Model
645
+ # # composite key
646
+ # set_primary_key [:taggable_id, :tag_id]
647
+ # end
648
+ def set_primary_key(key)
649
+ clear_setter_methods_cache
650
+ if key.is_a?(Array)
651
+ if key.length < 2
652
+ key = key.first
653
+ else
654
+ key = key.dup.freeze
655
+ end
656
+ end
657
+ self.simple_pk = if key && !key.is_a?(Array)
658
+ (@dataset || db).literal(key).freeze
659
+ end
660
+ @primary_key = key
661
+ end
662
+
663
+ # Cache of setter methods to allow by default, in order to speed up mass assignment.
664
+ def setter_methods
665
+ @setter_methods || (@setter_methods = get_setter_methods)
666
+ end
667
+
668
+ # Returns name of primary table for the dataset. If the table for the dataset
669
+ # is aliased, returns the aliased name.
670
+ #
671
+ # Artist.table_name # => :artists
672
+ # Sequel::Model(:foo).table_name # => :foo
673
+ # Sequel::Model(Sequel[:foo].as(:bar)).table_name # => :bar
674
+ def table_name
675
+ dataset.first_source_alias
676
+ end
677
+
678
+ # Allow the setting of the primary key(s) when using the mass assignment methods.
679
+ # Using this method can open up security issues, be very careful before using it.
680
+ #
681
+ # Artist.set(id: 1) # Error
682
+ # Artist.unrestrict_primary_key
683
+ # Artist.set(id: 1) # No Error
684
+ def unrestrict_primary_key
685
+ clear_setter_methods_cache
686
+ @restrict_primary_key = false
687
+ end
688
+
689
+ # Return the model instance with the primary key, or nil if there is no matching record.
690
+ def with_pk(pk)
691
+ primary_key_lookup(pk)
692
+ end
693
+
694
+ # Return the model instance with the primary key, or raise NoMatchingRow if there is no matching record.
695
+ def with_pk!(pk)
696
+ with_pk(pk) || raise(NoMatchingRow.new(dataset))
697
+ end
698
+
699
+ # Add model methods that call dataset methods
700
+ Plugins.def_dataset_methods(self, (Dataset::ACTION_METHODS + Dataset::QUERY_METHODS + [:any?, :each_server]) - [:<<, :or, :[], :columns, :columns!, :delete, :update, :set_graph_aliases, :add_graph_aliases])
701
+
702
+ private
703
+
704
+ # Yield to the passed block and if do_raise is false, swallow Sequel::Errors other than DatabaseConnectionError
705
+ # and DatabaseDisconnectError.
706
+ def check_non_connection_error(do_raise=require_valid_table)
707
+ db.transaction(:savepoint=>:only){yield}
708
+ rescue Sequel::DatabaseConnectionError, Sequel::DatabaseDisconnectError
709
+ raise
710
+ rescue Sequel::Error
711
+ raise if do_raise
712
+ end
713
+
714
+ # Convert the given object to a Dataset that should be used as
715
+ # this model's dataset.
716
+ def convert_input_dataset(ds)
717
+ case ds
718
+ when Symbol, SQL::Identifier, SQL::QualifiedIdentifier
719
+ self.simple_table = db.literal(ds).freeze
720
+ ds = db.from(ds)
721
+ when SQL::AliasedExpression, LiteralString
722
+ self.simple_table = nil
723
+ ds = db.from(ds)
724
+ when Dataset
725
+ ds = ds.from_self(:alias=>ds.first_source) if ds.joined_dataset?
726
+
727
+ self.simple_table = if ds.send(:simple_select_all?)
728
+ ds.literal(ds.first_source_table).freeze
729
+ end
730
+ @db = ds.db
731
+ else
732
+ raise(Error, "Model.set_dataset takes one of the following classes as an argument: Symbol, LiteralString, SQL::Identifier, SQL::QualifiedIdentifier, SQL::AliasedExpression, Dataset")
733
+ end
734
+
735
+ set_dataset_row_proc(ds.clone(:model=>self))
736
+ end
737
+
738
+ # Add the module to the class's dataset_method_modules. Extend the dataset with the
739
+ # module if the model has a dataset. Add dataset methods to the class for all
740
+ # public dataset methods.
741
+ def dataset_extend(mod, opts=OPTS)
742
+ @dataset = @dataset.with_extend(mod) if @dataset
743
+ reset_instance_dataset
744
+ dataset_method_modules << mod
745
+ unless opts[:create_class_methods] == false
746
+ mod.public_instance_methods.each{|meth| def_model_dataset_method(meth)}
747
+ end
748
+ end
749
+
750
+ # Create a column accessor for a column with a method name that is hard to use in ruby code.
751
+ def def_bad_column_accessor(column)
752
+ im = instance_methods
753
+ overridable_methods_module.module_eval do
754
+ meth = :"#{column}="
755
+ unless im.include?(column)
756
+ define_method(column){self[column]}
757
+ alias_method(column, column)
758
+ end
759
+ unless im.include?(meth)
760
+ define_method(meth){|v| self[column] = v}
761
+ alias_method(meth, meth)
762
+ end
763
+ end
764
+ end
765
+
766
+ # Create the column accessors. For columns that can be used as method names directly in ruby code,
767
+ # use a string to define the method for speed. For other columns names, use a block.
768
+ def def_column_accessor(*columns)
769
+ clear_setter_methods_cache
770
+ columns, bad_columns = columns.partition{|x| /\A[A-Za-z_][A-Za-z0-9_]*\z/.match(x.to_s)}
771
+ bad_columns.each{|x| def_bad_column_accessor(x)}
772
+ im = instance_methods
773
+ columns.each do |column|
774
+ meth = :"#{column}="
775
+ unless im.include?(column)
776
+ overridable_methods_module.module_eval("def #{column}; self[:#{column}] end", __FILE__, __LINE__)
777
+ overridable_methods_module.send(:alias_method, column, column)
778
+ end
779
+ unless im.include?(meth)
780
+ overridable_methods_module.module_eval("def #{meth}(v); self[:#{column}] = v end", __FILE__, __LINE__)
781
+ overridable_methods_module.send(:alias_method, meth, meth)
782
+ end
783
+ end
784
+ end
785
+
786
+ # Module that the class methods that call dataset methods are kept in.
787
+ # This allows the methods to be overridden and call super with the
788
+ # default behavior.
789
+ def dataset_methods_module
790
+ return @dataset_methods_module if defined?(@dataset_methods_module)
791
+ mod_name = "#{name}::@dataset_methods_module"
792
+ Sequel.synchronize{@dataset_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
793
+ extend(@dataset_methods_module)
794
+ @dataset_methods_module
795
+ end
796
+
797
+ # Define a model method that calls the dataset method with the same name.
798
+ def def_model_dataset_method(meth)
799
+ return if respond_to?(meth, true)
800
+
801
+ mod = dataset_methods_module
802
+
803
+ if meth.to_s =~ /\A[A-Za-z_][A-Za-z0-9_]*\z/
804
+ mod.module_eval(<<END, __FILE__, __LINE__ + 1)
805
+ def #{meth}(*args, &block); dataset.#{meth}(*args, &block) end
806
+ ruby2_keywords :#{meth} if respond_to?(:ruby2_keywords, true)
807
+ END
808
+ else
809
+ mod.send(:define_method, meth){|*args, &block| dataset.public_send(meth, *args, &block)}
810
+ # :nocov:
811
+ mod.send(:ruby2_keywords, meth) if respond_to?(:ruby2_keywords, true)
812
+ # :nocov:
813
+ end
814
+ mod.send(:alias_method, meth, meth)
815
+ end
816
+
817
+ # Get the schema from the database, fall back on checking the columns
818
+ # via the database if that will return inaccurate results or if
819
+ # it raises an error.
820
+ def get_db_schema(reload = reload_db_schema?)
821
+ set_columns(nil)
822
+ return nil unless @dataset
823
+ schema_hash = {}
824
+ ds_opts = dataset.opts
825
+ get_columns = proc{check_non_connection_error{columns} || []}
826
+ schema_array = get_db_schema_array(reload) if db.supports_schema_parsing?
827
+ if schema_array
828
+ schema_array.each{|k,v| schema_hash[k] = v}
829
+
830
+ # Set the primary key(s) based on the schema information,
831
+ # if the schema information includes primary key information
832
+ if schema_array.all?{|k,v| v.has_key?(:primary_key)}
833
+ pks = schema_array.map{|k,v| k if v[:primary_key]}.compact
834
+ pks.length > 0 ? set_primary_key(pks) : no_primary_key
835
+ end
836
+
837
+ if (select = ds_opts[:select]) && !(select.length == 1 && select.first.is_a?(SQL::ColumnAll))
838
+ # We don't remove the columns from the schema_hash,
839
+ # as it's possible they will be used for typecasting
840
+ # even if they are not selected.
841
+ cols = get_columns.call
842
+ cols.each{|c| schema_hash[c] ||= {}}
843
+ def_column_accessor(*schema_hash.keys)
844
+ else
845
+ # Dataset is for a single table with all columns,
846
+ # so set the columns based on the order they were
847
+ # returned by the schema.
848
+ cols = schema_array.map{|k,v| k}
849
+ set_columns(cols)
850
+ # Also set the columns for the dataset, so the dataset
851
+ # doesn't have to do a query to get them.
852
+ dataset.send(:columns=, cols)
853
+ end
854
+ else
855
+ # If the dataset uses multiple tables or custom sql or getting
856
+ # the schema raised an error, just get the columns and
857
+ # create an empty schema hash for it.
858
+ get_columns.call.each{|c| schema_hash[c] = {}}
859
+ end
860
+ schema_hash
861
+ end
862
+
863
+ # Get the array of schema information for the dataset. Returns nil if
864
+ # the schema information cannot be determined.
865
+ def get_db_schema_array(reload)
866
+ check_non_connection_error(false){db.schema(dataset, :reload=>reload)}
867
+ end
868
+
869
+ # Uncached version of setter_methods, to be overridden by plugins
870
+ # that want to modify the methods used.
871
+ def get_setter_methods
872
+ meths = instance_methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
873
+ meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && restrict_primary_key?
874
+ meths
875
+ end
876
+
877
+ # If possible, set the dataset for the model subclass as soon as it
878
+ # is created. Also, make sure the inherited class instance variables
879
+ # are copied into the subclass.
880
+ #
881
+ # Sequel queries the database to get schema information as soon as
882
+ # a model class is created:
883
+ #
884
+ # class Artist < Sequel::Model # Causes schema query
885
+ # end
886
+ def inherited(subclass)
887
+ super
888
+ ivs = subclass.instance_variables
889
+ inherited_instance_variables.each do |iv, dup|
890
+ if (sup_class_value = instance_variable_get(iv)) && dup
891
+ sup_class_value = case dup
892
+ when :dup
893
+ sup_class_value.dup
894
+ when :hash_dup
895
+ h = {}
896
+ sup_class_value.each{|k,v| h[k] = v.dup}
897
+ h
898
+ when Proc
899
+ dup.call(sup_class_value)
900
+ else
901
+ raise Error, "bad inherited instance variable type: #{dup.inspect}"
902
+ end
903
+ end
904
+ subclass.instance_variable_set(iv, sup_class_value)
905
+ end
906
+
907
+ unless ivs.include?(:@dataset)
908
+ if @dataset && self != Model
909
+ subclass.set_dataset(@dataset.clone, :inherited=>true)
910
+ elsif (n = subclass.name) && !n.to_s.empty?
911
+ db
912
+ subclass.set_dataset(subclass.implicit_table_name)
913
+ end
914
+ end
915
+ end
916
+
917
+ # A hash of instance variables to automatically set up in subclasses.
918
+ # Keys are instance variable symbols, values should be:
919
+ # nil :: Assign directly from superclass to subclass (frozen objects)
920
+ # :dup :: Dup object when assigning from superclass to subclass (mutable objects)
921
+ # :hash_dup :: Assign hash with same keys, but dup all the values
922
+ # Proc :: Call with subclass to do the assignment
923
+ def inherited_instance_variables
924
+ {
925
+ :@cache_anonymous_models=>nil,
926
+ :@dataset_method_modules=>:dup,
927
+ :@dataset_module_class=>nil,
928
+ :@db=>nil,
929
+ :@default_set_fields_options=>:dup,
930
+ :@fast_instance_delete_sql=>nil,
931
+ :@fast_pk_lookup_sql=>nil,
932
+ :@plugins=>:dup,
933
+ :@primary_key=>nil,
934
+ :@raise_on_save_failure=>nil,
935
+ :@raise_on_typecast_failure=>nil,
936
+ :@require_modification=>nil,
937
+ :@require_valid_table=>nil,
938
+ :@restrict_primary_key=>nil,
939
+ :@setter_methods=>nil,
940
+ :@simple_pk=>nil,
941
+ :@simple_table=>nil,
942
+ :@strict_param_setting=>nil,
943
+ :@typecast_empty_string_to_nil=>nil,
944
+ :@typecast_on_assignment=>nil,
945
+ :@use_transactions=>nil
946
+ }
947
+ end
948
+
949
+ # For the given opts hash and default name or :class option, add a
950
+ # :class_name option unless already present which contains the name
951
+ # of the class to use as a string. The purpose is to allow late
952
+ # binding to the class later using constantize.
953
+ def late_binding_class_option(opts, default)
954
+ case opts[:class]
955
+ when String, Symbol
956
+ # Delete :class to allow late binding
957
+ class_name = opts.delete(:class).to_s
958
+
959
+ if (namespace = opts[:class_namespace]) && !class_name.start_with?('::')
960
+ class_name = "::#{namespace}::#{class_name}"
961
+ end
962
+
963
+ opts[:class_name] ||= class_name
964
+ when Class
965
+ opts[:class_name] ||= opts[:class].name
966
+ end
967
+
968
+ opts[:class_name] ||= '::' + ((name || '').split("::")[0..-2] + [camelize(default)]).join('::')
969
+ end
970
+
971
+ # Clear the setter_methods cache when a setter method is added.
972
+ def method_added(meth)
973
+ clear_setter_methods_cache if meth.to_s.end_with?('=')
974
+ super
975
+ end
976
+
977
+ # Module that the class includes that holds methods the class adds for column accessors and
978
+ # associations so that the methods can be overridden with +super+.
979
+ def overridable_methods_module
980
+ return @overridable_methods_module if defined?(@overridable_methods_module)
981
+ mod_name = "#{name}::@overridable_methods_module"
982
+ Sequel.synchronize{@overridable_methods_module ||= Sequel.set_temp_name(Module.new){mod_name}}
983
+ include(@overridable_methods_module)
984
+ @overridable_methods_module
985
+ end
986
+
987
+ # Returns the module for the specified plugin. If the module is not
988
+ # defined, the corresponding plugin required.
989
+ def plugin_module(plugin)
990
+ module_name = plugin.to_s.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
991
+ unless Sequel::Plugins.const_defined?(module_name, false)
992
+ require "sequel/plugins/#{plugin}"
993
+ end
994
+ Sequel::Plugins.const_get(module_name)
995
+ end
996
+
997
+ # Find the row in the dataset that matches the primary key. Uses
998
+ # a static SQL optimization if the table and primary key are simple.
999
+ #
1000
+ # This method should not be called with a nil primary key, in case
1001
+ # it is overridden by plugins which assume that the passed argument
1002
+ # is valid.
1003
+ def primary_key_lookup(pk)
1004
+ if sql = @fast_pk_lookup_sql
1005
+ sql = sql.dup
1006
+ ds = dataset
1007
+ ds.literal_append(sql, pk)
1008
+ ds.fetch_rows(sql){|r| return ds.row_proc.call(r)}
1009
+ nil
1010
+ else
1011
+ dataset.first(primary_key_hash(pk))
1012
+ end
1013
+ end
1014
+
1015
+ # Whether to reload the database schema by default, ignoring any cached value.
1016
+ def reload_db_schema?
1017
+ false
1018
+ end
1019
+
1020
+ # Reset the cached fast primary lookup SQL if a simple table and primary key
1021
+ # are used, or set it to nil if not used.
1022
+ def reset_fast_pk_lookup_sql
1023
+ @fast_pk_lookup_sql = if @simple_table && @simple_pk
1024
+ "SELECT * FROM #{@simple_table} WHERE #{@simple_pk} = ".freeze
1025
+ end
1026
+ @fast_instance_delete_sql = if @simple_table && @simple_pk
1027
+ "DELETE FROM #{@simple_table} WHERE #{@simple_pk} = ".freeze
1028
+ end
1029
+ end
1030
+
1031
+ # Reset the instance dataset to a modified copy of the current dataset,
1032
+ # should be used whenever the model's dataset is modified.
1033
+ def reset_instance_dataset
1034
+ @instance_dataset = @dataset.limit(1).naked.skip_limit_check if @dataset
1035
+ end
1036
+
1037
+ # Set the columns for this model and create accessor methods for each column.
1038
+ def set_columns(new_columns)
1039
+ @columns = new_columns
1040
+ def_column_accessor(*new_columns) if new_columns
1041
+ @columns
1042
+ end
1043
+
1044
+ # Set the dataset's row_proc to the current model.
1045
+ def set_dataset_row_proc(ds)
1046
+ ds.with_row_proc(self)
1047
+ end
1048
+
1049
+ # Reset the fast primary key lookup SQL when the simple_pk value changes.
1050
+ def simple_pk=(pk)
1051
+ @simple_pk = pk
1052
+ reset_fast_pk_lookup_sql
1053
+ end
1054
+
1055
+ # Reset the fast primary key lookup SQL when the simple_table value changes.
1056
+ def simple_table=(t)
1057
+ @simple_table = t
1058
+ reset_fast_pk_lookup_sql
1059
+ end
1060
+
1061
+ # Returns a copy of the model's dataset with custom SQL
1062
+ #
1063
+ # Artist.fetch("SELECT * FROM artists WHERE name LIKE 'A%'")
1064
+ # Artist.fetch("SELECT * FROM artists WHERE id = ?", 1)
1065
+ alias fetch with_sql
1066
+ end
1067
+
1068
+ # Sequel::Model instance methods that implement basic model functionality.
1069
+ #
1070
+ # * All of the model before/after/around hooks are implemented as instance methods that are called
1071
+ # by Sequel when the appropriate action occurs. For example, when destroying
1072
+ # a model object, Sequel will call +around_destroy+, which will call +before_destroy+, do
1073
+ # the destroy, and then call +after_destroy+.
1074
+ # * The following instance_methods all call the class method of the same
1075
+ # name: columns, db, primary_key, db_schema.
1076
+ # * The following accessor methods are defined via metaprogramming:
1077
+ # raise_on_save_failure, raise_on_typecast_failure, require_modification,
1078
+ # strict_param_setting, typecast_empty_string_to_nil, typecast_on_assignment,
1079
+ # and use_transactions. The setter methods will change the setting for the
1080
+ # instance, and the getter methods will check for an instance setting, then
1081
+ # try the class setting if no instance setting has been set.
1082
+ module InstanceMethods
1083
+ HOOKS.each{|h| class_eval("def #{h}; end", __FILE__, __LINE__)}
1084
+ [:around_create, :around_update, :around_save, :around_destroy, :around_validation].each{|h| class_eval("def #{h}; yield end", __FILE__, __LINE__)}
1085
+
1086
+ # Define instance method(s) that calls class method(s) of the
1087
+ # same name. Replaces the construct:
1088
+ #
1089
+ # define_method(meth){self.class.public_send(meth)}
1090
+ [:columns, :db, :primary_key, :db_schema].each{|meth| class_eval("def #{meth}; self.class.#{meth} end", __FILE__, __LINE__)}
1091
+
1092
+ # Define instance method(s) that calls class method(s) of the
1093
+ # same name, caching the result in an instance variable. Define
1094
+ # standard attr_writer method for modifying that instance variable.
1095
+ [:typecast_empty_string_to_nil, :typecast_on_assignment, :strict_param_setting,
1096
+ :raise_on_save_failure, :raise_on_typecast_failure, :require_modification, :use_transactions].each do |meth|
1097
+ class_eval("def #{meth}; !defined?(@#{meth}) ? (frozen? ? self.class.#{meth} : (@#{meth} = self.class.#{meth})) : @#{meth} end", __FILE__, __LINE__)
1098
+ attr_writer(meth)
1099
+ end
1100
+
1101
+ # The hash of attribute values. Keys are symbols with the names of the
1102
+ # underlying database columns. The returned hash is a reference to the
1103
+ # receiver's values hash, and modifying it will also modify the receiver's
1104
+ # values.
1105
+ #
1106
+ # Artist.new(name: 'Bob').values # => {:name=>'Bob'}
1107
+ # Artist[1].values # => {:id=>1, :name=>'Jim', ...}
1108
+ attr_reader :values
1109
+ alias to_hash values
1110
+
1111
+ # Get the value of the column. Takes a single symbol or string argument.
1112
+ # By default it calls send with the argument to get the value. This can
1113
+ # be overridden if you have columns that conflict with existing
1114
+ # method names.
1115
+ alias get_column_value send
1116
+
1117
+ # Set the value of the column. Takes two arguments. The first is a
1118
+ # symbol or string argument for the column name, suffixed with =. The
1119
+ # second is the value to set for the column. By default it calls send
1120
+ # with the argument to set the value. This can be overridden if you have
1121
+ # columns that conflict with existing method names (unlikely for setter
1122
+ # methods, but possible).
1123
+ alias set_column_value send
1124
+
1125
+ # Creates new instance and passes the given values to set.
1126
+ # If a block is given, yield the instance to the block.
1127
+ #
1128
+ # Arguments:
1129
+ # values :: should be a hash to pass to set.
1130
+ #
1131
+ # Artist.new(name: 'Bob')
1132
+ #
1133
+ # Artist.new do |a|
1134
+ # a.name = 'Bob'
1135
+ # end
1136
+ def initialize(values = OPTS)
1137
+ @values = {}
1138
+ @new = true
1139
+ @modified = true
1140
+ initialize_set(values)
1141
+ _clear_changed_columns(:initialize)
1142
+ yield self if defined?(yield)
1143
+ end
1144
+
1145
+ # Returns value of the column's attribute.
1146
+ #
1147
+ # Artist[1][:id] #=> 1
1148
+ def [](column)
1149
+ @values[column]
1150
+ end
1151
+
1152
+ # Sets the value for the given column. If typecasting is enabled for
1153
+ # this object, typecast the value based on the column's type.
1154
+ # If this is a new record or the typecasted value isn't the same
1155
+ # as the current value for the column, mark the column as changed.
1156
+ #
1157
+ # a = Artist.new
1158
+ # a[:name] = 'Bob'
1159
+ # a.values #=> {:name=>'Bob'}
1160
+ def []=(column, value)
1161
+ # If it is new, it doesn't have a value yet, so we should
1162
+ # definitely set the new value.
1163
+ # If the column isn't in @values, we can't assume it is
1164
+ # NULL in the database, so assume it has changed.
1165
+ v = typecast_value(column, value)
1166
+ vals = @values
1167
+ if new? || !vals.include?(column) || v != (c = vals[column]) || v.class != c.class
1168
+ change_column_value(column, v)
1169
+ end
1170
+ end
1171
+
1172
+ # Alias of eql?
1173
+ def ==(obj)
1174
+ eql?(obj)
1175
+ end
1176
+
1177
+ # Case equality. By default, checks equality of the primary key value, see
1178
+ # pk_equal?.
1179
+ #
1180
+ # Artist[1] === Artist[1] # => true
1181
+ # Artist.new === Artist.new # => false
1182
+ # Artist[1].set(name: 'Bob') === Artist[1] # => true
1183
+ def ===(obj)
1184
+ case pkv = pk
1185
+ when nil
1186
+ return false
1187
+ when Array
1188
+ return false if pkv.any?(&:nil?)
1189
+ end
1190
+
1191
+ (obj.class == model) && (obj.pk == pkv)
1192
+ end
1193
+
1194
+ # If the receiver has a primary key value, returns true if the objects have
1195
+ # the same class and primary key value.
1196
+ # If the receiver's primary key value is nil or is an array containing
1197
+ # nil, returns false.
1198
+ #
1199
+ # Artist[1].pk_equal?(Artist[1]) # => true
1200
+ # Artist.new.pk_equal?(Artist.new) # => false
1201
+ # Artist[1].set(name: 'Bob').pk_equal?(Artist[1]) # => true
1202
+ alias pk_equal? ===
1203
+
1204
+ # class is defined in Object, but it is also a keyword,
1205
+ # and since a lot of instance methods call class methods,
1206
+ # this alias makes it so you can use model instead of
1207
+ # self.class.
1208
+ #
1209
+ # Artist.new.model # => Artist
1210
+ alias_method :model, :class
1211
+
1212
+ # The autoincrementing primary key for this model object. Should be
1213
+ # overridden if you have a composite primary key with one part of it
1214
+ # being autoincrementing.
1215
+ def autoincrementing_primary_key
1216
+ primary_key
1217
+ end
1218
+
1219
+ # Cancel the current action. Should be called in before hooks to halt
1220
+ # the processing of the action. If a +msg+ argument is given and
1221
+ # the model instance is configured to raise exceptions on failure,
1222
+ # sets the message to use for the raised HookFailed exception.
1223
+ def cancel_action(msg=nil)
1224
+ raise_hook_failure(msg)
1225
+ end
1226
+
1227
+ # The columns that have been updated. This isn't completely accurate,
1228
+ # as it could contain columns whose values have not changed.
1229
+ #
1230
+ # a = Artist[1]
1231
+ # a.changed_columns # => []
1232
+ # a.name = 'Bob'
1233
+ # a.changed_columns # => [:name]
1234
+ def changed_columns
1235
+ _changed_columns
1236
+ end
1237
+
1238
+ # Deletes and returns +self+. Does not run destroy hooks.
1239
+ # Look into using +destroy+ instead.
1240
+ #
1241
+ # Artist[1].delete # DELETE FROM artists WHERE (id = 1)
1242
+ # # => #<Artist {:id=>1, ...}>
1243
+ def delete
1244
+ raise Sequel::Error, "can't delete frozen object" if frozen?
1245
+ _delete
1246
+ self
1247
+ end
1248
+
1249
+ # Like delete but runs hooks before and after delete.
1250
+ # Uses a transaction if use_transactions is true or if the
1251
+ # :transaction option is given and true.
1252
+ #
1253
+ # Artist[1].destroy # BEGIN; DELETE FROM artists WHERE (id = 1); COMMIT;
1254
+ # # => #<Artist {:id=>1, ...}>
1255
+ def destroy(opts = OPTS)
1256
+ raise Sequel::Error, "can't destroy frozen object" if frozen?
1257
+ checked_save_failure(opts){checked_transaction(opts){_destroy(opts)}}
1258
+ end
1259
+
1260
+ # Iterates through all of the current values using each.
1261
+ #
1262
+ # Album[1].each{|k, v| puts "#{k} => #{v}"}
1263
+ # # id => 1
1264
+ # # name => 'Bob'
1265
+ def each(&block)
1266
+ @values.each(&block)
1267
+ end
1268
+
1269
+ # Compares model instances by values.
1270
+ #
1271
+ # Artist[1] == Artist[1] # => true
1272
+ # Artist.new == Artist.new # => true
1273
+ # Artist[1].set(name: 'Bob') == Artist[1] # => false
1274
+ def eql?(obj)
1275
+ (obj.class == model) && (obj.values == @values)
1276
+ end
1277
+
1278
+ # Returns the validation errors associated with this object.
1279
+ # See +Errors+.
1280
+ def errors
1281
+ @errors ||= errors_class.new
1282
+ end
1283
+
1284
+ EXISTS_SELECT_ = SQL::AliasedExpression.new(1, :one)
1285
+ private_constant :EXISTS_SELECT_
1286
+
1287
+ # Returns true when current instance exists, false otherwise.
1288
+ # Generally an object that isn't new will exist unless it has
1289
+ # been deleted. Uses a database query to check for existence,
1290
+ # unless the model object is new, in which case this is always
1291
+ # false.
1292
+ #
1293
+ # Artist[1].exists? # SELECT 1 AS one FROM artists WHERE (id = 1)
1294
+ # # => true
1295
+ # Artist.new.exists?
1296
+ # # => false
1297
+ def exists?
1298
+ new? ? false : !this.get(EXISTS_SELECT_).nil?
1299
+ end
1300
+
1301
+ # Ignore the model's setter method cache when this instances extends a module, as the
1302
+ # module may contain setter methods.
1303
+ def extend(mod)
1304
+ @singleton_setter_added = true
1305
+ super
1306
+ end
1307
+
1308
+ # Freeze the object in such a way that it is still usable but not modifiable.
1309
+ # Once an object is frozen, you cannot modify it's values, changed_columns,
1310
+ # errors, or dataset.
1311
+ def freeze
1312
+ unless errors.frozen?
1313
+ validate
1314
+ errors.freeze
1315
+ end
1316
+ values.freeze
1317
+ _changed_columns.freeze
1318
+ this if !new? && model.primary_key
1319
+ super
1320
+ end
1321
+
1322
+ # Value that should be unique for objects with the same class and pk (if pk is not nil), or
1323
+ # the same class and values (if pk is nil).
1324
+ #
1325
+ # Artist[1].hash == Artist[1].hash # true
1326
+ # Artist[1].set(name: 'Bob').hash == Artist[1].hash # true
1327
+ # Artist.new.hash == Artist.new.hash # true
1328
+ # Artist.new(name: 'Bob').hash == Artist.new.hash # false
1329
+ def hash
1330
+ case primary_key
1331
+ when Array
1332
+ [model, !pk.all? ? @values : pk].hash
1333
+ when Symbol
1334
+ [model, pk.nil? ? @values : pk].hash
1335
+ else
1336
+ [model, @values].hash
1337
+ end
1338
+ end
1339
+
1340
+ # Returns value for the :id attribute, even if the primary key is
1341
+ # not id. To get the primary key value, use +pk+.
1342
+ #
1343
+ # Artist[1].id # => 1
1344
+ def id
1345
+ @values[:id]
1346
+ end
1347
+
1348
+ # Returns a string representation of the model instance including
1349
+ # the class name and values.
1350
+ def inspect
1351
+ "#<#{inspect_prefix} @values=#{inspect_values}>"
1352
+ end
1353
+
1354
+ # Returns the keys in +values+. May not include all column names.
1355
+ #
1356
+ # Artist.new.keys # => []
1357
+ # Artist.new(name: 'Bob').keys # => [:name]
1358
+ # Artist[1].keys # => [:id, :name]
1359
+ def keys
1360
+ @values.keys
1361
+ end
1362
+
1363
+ # Refresh this record using +:update+ lock style (by default, or the specified style when given),
1364
+ # unless this is a new record. Returns self. This can be used to make sure no other
1365
+ # process can modify the record during the transaction containing this call. Using
1366
+ # this method only makes sense inside transactions.
1367
+ #
1368
+ # If style is a string, it will be used directly. You should never pass a string
1369
+ # to this method that is derived from user input, as that can lead to
1370
+ # SQL injection.
1371
+ #
1372
+ # A symbol may be used if the adapter supports that lock style.
1373
+ #
1374
+ # a = Artist[1]
1375
+ # Artist.db.transaction do
1376
+ # a.lock!
1377
+ # a.update(name: 'A')
1378
+ # end
1379
+ #
1380
+ # a = Artist[2]
1381
+ # Artist.db.transaction do
1382
+ # a.lock!(:no_key_update)
1383
+ # a.update(name: 'B')
1384
+ # end
1385
+ def lock!(style=:update)
1386
+ _refresh(this.lock_style(style)) unless new?
1387
+ self
1388
+ end
1389
+
1390
+ # Remove elements of the model object that make marshalling fail. Returns self.
1391
+ #
1392
+ # a = Artist[1]
1393
+ # a.marshallable!
1394
+ # Marshal.dump(a)
1395
+ def marshallable!
1396
+ @this = nil
1397
+ self
1398
+ end
1399
+
1400
+ # Explicitly mark the object as modified, so +save_changes+/+update+ will
1401
+ # run callbacks even if no columns have changed.
1402
+ #
1403
+ # a = Artist[1]
1404
+ # a.save_changes # No callbacks run, as no changes
1405
+ # a.modified!
1406
+ # a.save_changes # Callbacks run, even though no changes made
1407
+ #
1408
+ # If a column is given, specifically marked that column as modified,
1409
+ # so that +save_changes+/+update+ will include that column in the
1410
+ # update. This should be used if you plan on mutating the column
1411
+ # value instead of assigning a new column value:
1412
+ #
1413
+ # a.modified!(:name)
1414
+ # a.name.gsub!(/[aeou]/, 'i')
1415
+ def modified!(column=nil)
1416
+ _add_changed_column(column) if column
1417
+ @modified = true
1418
+ end
1419
+
1420
+ # Whether this object has been modified since last saved, used by
1421
+ # save_changes to determine whether changes should be saved. New
1422
+ # values are always considered modified.
1423
+ #
1424
+ # a = Artist[1]
1425
+ # a.modified? # => false
1426
+ # a.set(name: 'Jim')
1427
+ # a.modified? # => true
1428
+ #
1429
+ # If a column is given, specifically check if the given column has
1430
+ # been modified:
1431
+ #
1432
+ # a.modified?(:num_albums) # => false
1433
+ # a.num_albums = 10
1434
+ # a.modified?(:num_albums) # => true
1435
+ def modified?(column=nil)
1436
+ if column
1437
+ changed_columns.include?(column)
1438
+ else
1439
+ @modified || !changed_columns.empty?
1440
+ end
1441
+ end
1442
+
1443
+ # Returns true if the current instance represents a new record.
1444
+ #
1445
+ # Artist.new.new? # => true
1446
+ # Artist[1].new? # => false
1447
+ def new?
1448
+ defined?(@new) ? @new : (@new = false)
1449
+ end
1450
+
1451
+ # Returns the primary key value identifying the model instance.
1452
+ # Raises an +Error+ if this model does not have a primary key.
1453
+ # If the model has a composite primary key, returns an array of values.
1454
+ #
1455
+ # Artist[1].pk # => 1
1456
+ # Artist[[1, 2]].pk # => [1, 2]
1457
+ def pk
1458
+ raise(Error, "No primary key is associated with this model") unless key = primary_key
1459
+ if key.is_a?(Array)
1460
+ vals = @values
1461
+ key.map{|k| vals[k]}
1462
+ else
1463
+ @values[key]
1464
+ end
1465
+ end
1466
+
1467
+ # Returns a hash mapping the receivers primary key column(s) to their values.
1468
+ #
1469
+ # Artist[1].pk_hash # => {:id=>1}
1470
+ # Artist[[1, 2]].pk_hash # => {:id1=>1, :id2=>2}
1471
+ def pk_hash
1472
+ model.primary_key_hash(pk)
1473
+ end
1474
+
1475
+ # Returns a hash mapping the receivers qualified primary key column(s) to their values.
1476
+ #
1477
+ # Artist[1].qualified_pk_hash
1478
+ # # => {Sequel[:artists][:id]=>1}
1479
+ # Artist[[1, 2]].qualified_pk_hash
1480
+ # # => {Sequel[:artists][:id1]=>1, Sequel[:artists][:id2]=>2}
1481
+ def qualified_pk_hash(qualifier=model.table_name)
1482
+ model.qualified_primary_key_hash(pk, qualifier)
1483
+ end
1484
+
1485
+ # Reloads attributes from database and returns self. Also clears all
1486
+ # changed_columns information. Raises an +Error+ if the record no longer
1487
+ # exists in the database.
1488
+ #
1489
+ # a = Artist[1]
1490
+ # a.name = 'Jim'
1491
+ # a.refresh
1492
+ # a.name # => 'Bob'
1493
+ def refresh
1494
+ raise Sequel::Error, "can't refresh frozen object" if frozen?
1495
+ _refresh(this)
1496
+ self
1497
+ end
1498
+
1499
+ # Alias of refresh, but not aliased directly to make overriding in a plugin easier.
1500
+ def reload
1501
+ refresh
1502
+ end
1503
+
1504
+ # Remove a key from the instances values, and return the value
1505
+ # of the key.
1506
+ #
1507
+ # a = Album[1]
1508
+ # a.values
1509
+ # # => {id: 1, artist_id: 2}
1510
+ # a.remove_key!(:artist_id)
1511
+ # # => 2
1512
+ # a.values
1513
+ # # => {id: 1}
1514
+ def remove_key!(key)
1515
+ @values.delete(key)
1516
+ end
1517
+
1518
+ # Creates or updates the record, after making sure the record
1519
+ # is valid and before hooks execute successfully. Fails if:
1520
+ #
1521
+ # * the record is not valid, or
1522
+ # * before_save calls cancel_action, or
1523
+ # * the record is new and before_create calls cancel_action, or
1524
+ # * the record is not new and before_update calls cancel_action.
1525
+ #
1526
+ # If +save+ fails and either raise_on_save_failure or the
1527
+ # :raise_on_failure option is true, it raises ValidationFailed
1528
+ # or HookFailed. Otherwise it returns nil.
1529
+ #
1530
+ # If it succeeds, it returns self.
1531
+ #
1532
+ # Takes the following options:
1533
+ #
1534
+ # :changed :: save all changed columns, instead of all columns or the columns given
1535
+ # :columns :: array of specific columns that should be saved.
1536
+ # :raise_on_failure :: set to true or false to override the current
1537
+ # +raise_on_save_failure+ setting
1538
+ # :server :: set the server/shard on the object before saving, and use that
1539
+ # server/shard in any transaction.
1540
+ # :transaction :: set to true or false to override the current
1541
+ # +use_transactions+ setting
1542
+ # :validate :: set to false to skip validation
1543
+ def save(opts=OPTS)
1544
+ raise Sequel::Error, "can't save frozen object" if frozen?
1545
+ set_server(opts[:server]) if opts[:server]
1546
+ unless _save_valid?(opts)
1547
+ raise(validation_failed_error) if raise_on_failure?(opts)
1548
+ return
1549
+ end
1550
+ checked_save_failure(opts){checked_transaction(opts){_save(opts)}}
1551
+ end
1552
+
1553
+ # Saves only changed columns if the object has been modified.
1554
+ # If the object has not been modified, returns nil. If unable to
1555
+ # save, returns false unless +raise_on_save_failure+ is true.
1556
+ #
1557
+ # a = Artist[1]
1558
+ # a.save_changes # => nil
1559
+ # a.name = 'Jim'
1560
+ # a.save_changes # UPDATE artists SET name = 'Bob' WHERE (id = 1)
1561
+ # # => #<Artist {:id=>1, :name=>'Jim', ...}
1562
+ def save_changes(opts=OPTS)
1563
+ save(Hash[opts].merge!(:changed=>true)) || false if modified?
1564
+ end
1565
+
1566
+ # Updates the instance with the supplied values with support for virtual
1567
+ # attributes, raising an exception if a value is used that doesn't have
1568
+ # a setter method (or ignoring it if <tt>strict_param_setting = false</tt>).
1569
+ # Does not save the record.
1570
+ #
1571
+ # artist.set(name: 'Jim')
1572
+ # artist.name # => 'Jim'
1573
+ def set(hash)
1574
+ set_restricted(hash, :default)
1575
+ end
1576
+
1577
+ # For each of the fields in the given array +fields+, call the setter
1578
+ # method with the value of that +hash+ entry for the field. Returns self.
1579
+ #
1580
+ # You can provide an options hash, with the following options currently respected:
1581
+ # :missing :: Can be set to :skip to skip missing entries or :raise to raise an
1582
+ # Error for missing entries. The default behavior is not to check for
1583
+ # missing entries, in which case the default value is used. To be
1584
+ # friendly with most web frameworks, the missing check will also check
1585
+ # for the string version of the argument in the hash if given a symbol.
1586
+ #
1587
+ # Examples:
1588
+ #
1589
+ # artist.set_fields({name: 'Jim'}, [:name])
1590
+ # artist.name # => 'Jim'
1591
+ #
1592
+ # artist.set_fields({hometown: 'LA'}, [:name])
1593
+ # artist.name # => nil
1594
+ # artist.hometown # => 'Sac'
1595
+ #
1596
+ # artist.name # => 'Jim'
1597
+ # artist.set_fields({}, [:name], missing: :skip)
1598
+ # artist.name # => 'Jim'
1599
+ #
1600
+ # artist.name # => 'Jim'
1601
+ # artist.set_fields({}, [:name], missing: :raise)
1602
+ # # Sequel::Error raised
1603
+ def set_fields(hash, fields, opts=nil)
1604
+ opts = if opts
1605
+ model.default_set_fields_options.merge(opts)
1606
+ else
1607
+ model.default_set_fields_options
1608
+ end
1609
+
1610
+ case missing = opts[:missing]
1611
+ when :skip, :raise
1612
+ do_raise = true if missing == :raise
1613
+ fields.each do |f|
1614
+ if hash.has_key?(f)
1615
+ set_column_value("#{f}=", hash[f])
1616
+ elsif f.is_a?(Symbol) && hash.has_key?(sf = f.to_s)
1617
+ set_column_value("#{sf}=", hash[sf])
1618
+ elsif do_raise
1619
+ raise(Sequel::Error, "missing field in hash: #{f.inspect} not in #{hash.inspect}")
1620
+ end
1621
+ end
1622
+ else
1623
+ fields.each{|f| set_column_value("#{f}=", hash[f])}
1624
+ end
1625
+ self
1626
+ end
1627
+
1628
+ # Set the shard that this object is tied to. Returns self.
1629
+ def set_server(s)
1630
+ @server = s
1631
+ @this = @this.server(s) if @this
1632
+ self
1633
+ end
1634
+
1635
+ # Clear the setter_methods cache when a method is added
1636
+ def singleton_method_added(meth)
1637
+ @singleton_setter_added = true if meth.to_s.end_with?('=')
1638
+ super
1639
+ end
1640
+
1641
+ # Skip all validation of the object on the next call to #save,
1642
+ # including the running of validation hooks. This is designed for
1643
+ # and should only be used in cases where #valid? is called before
1644
+ # saving and the <tt>validate: false</tt> option cannot be passed to
1645
+ # #save.
1646
+ def skip_validation_on_next_save!
1647
+ @skip_validation_on_next_save = true
1648
+ end
1649
+
1650
+ # Returns naked dataset that should return only the row related to this instance.
1651
+ #
1652
+ # Artist[1].this
1653
+ # # SELECT * FROM artists WHERE (id = 1) LIMIT 1
1654
+ def this
1655
+ return @this if @this
1656
+ raise Error, "No dataset for model #{model}" unless ds = model.instance_dataset
1657
+ @this = use_server(ds.where(pk_hash))
1658
+ end
1659
+
1660
+ # Runs #set with the passed hash and then runs save_changes.
1661
+ #
1662
+ # artist.update(name: 'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1663
+ def update(hash)
1664
+ update_restricted(hash, :default)
1665
+ end
1666
+
1667
+ # Update the instance's values by calling set_fields with the arguments, then
1668
+ # calls save_changes.
1669
+ #
1670
+ # artist.update_fields({name: 'Jim'}, [:name])
1671
+ # # UPDATE artists SET name = 'Jim' WHERE (id = 1)
1672
+ #
1673
+ # artist.update_fields({hometown: 'LA'}, [:name])
1674
+ # # UPDATE artists SET name = NULL WHERE (id = 1)
1675
+ def update_fields(hash, fields, opts=nil)
1676
+ set_fields(hash, fields, opts)
1677
+ save_changes
1678
+ end
1679
+
1680
+ # Validates the object. If the object is invalid, errors should be added
1681
+ # to the errors attribute. By default, does nothing, as all models
1682
+ # are valid by default. See the {"Model Validations" guide}[rdoc-ref:doc/validations.rdoc].
1683
+ # for details about validation. Should not be called directly by
1684
+ # user code, call <tt>valid?</tt> instead to check if an object
1685
+ # is valid.
1686
+ def validate
1687
+ end
1688
+
1689
+ # Validates the object and returns true if no errors are reported.
1690
+ #
1691
+ # artist.set(name: 'Valid').valid? # => true
1692
+ # artist.set(name: 'Invalid').valid? # => false
1693
+ # artist.errors.full_messages # => ['name cannot be Invalid']
1694
+ def valid?(opts = OPTS)
1695
+ _valid?(opts)
1696
+ rescue HookFailed
1697
+ false
1698
+ end
1699
+
1700
+ private
1701
+
1702
+ # Add a column as a changed column.
1703
+ def _add_changed_column(column)
1704
+ cc = _changed_columns
1705
+ cc << column unless cc.include?(column)
1706
+ end
1707
+
1708
+ # Internal changed_columns method that just returns stored array.
1709
+ def _changed_columns
1710
+ @changed_columns ||= []
1711
+ end
1712
+
1713
+ # Clear the changed columns. Reason is the reason for clearing
1714
+ # the columns, and should be one of: :initialize, :refresh, :create
1715
+ # or :update.
1716
+ def _clear_changed_columns(_reason)
1717
+ _changed_columns.clear
1718
+ end
1719
+
1720
+ # Do the deletion of the object's dataset, and check that the row
1721
+ # was actually deleted.
1722
+ def _delete
1723
+ n = _delete_without_checking
1724
+ raise(NoExistingObject, "Attempt to delete object did not result in a single row modification (Rows Deleted: #{n}, SQL: #{_delete_dataset.delete_sql})") if require_modification && n != 1
1725
+ n
1726
+ end
1727
+
1728
+ # The dataset to use when deleting the object. The same as the object's
1729
+ # dataset by default.
1730
+ def _delete_dataset
1731
+ this
1732
+ end
1733
+
1734
+ # Actually do the deletion of the object's dataset. Return the
1735
+ # number of rows modified.
1736
+ def _delete_without_checking
1737
+ if sql = (m = model).fast_instance_delete_sql
1738
+ sql = sql.dup
1739
+ ds = use_server(m.dataset)
1740
+ ds.literal_append(sql, pk)
1741
+ ds.with_sql_delete(sql)
1742
+ else
1743
+ _delete_dataset.delete
1744
+ end
1745
+ end
1746
+
1747
+ # Internal destroy method, separted from destroy to
1748
+ # allow running inside a transaction
1749
+ def _destroy(opts)
1750
+ called = false
1751
+ around_destroy do
1752
+ called = true
1753
+ before_destroy
1754
+ _destroy_delete
1755
+ after_destroy
1756
+ end
1757
+ raise_hook_failure(:around_destroy) unless called
1758
+ self
1759
+ end
1760
+
1761
+ # Internal delete method to call when destroying an object,
1762
+ # separated from delete to allow you to override destroy's version
1763
+ # without affecting delete.
1764
+ def _destroy_delete
1765
+ delete
1766
+ end
1767
+
1768
+ # Insert the record into the database, returning the primary key if
1769
+ # the record should be refreshed from the database.
1770
+ def _insert
1771
+ ds = _insert_dataset
1772
+ if _use_insert_select?(ds) && !(h = _insert_select_raw(ds)).nil?
1773
+ _save_set_values(h) if h
1774
+ nil
1775
+ else
1776
+ iid = _insert_raw(ds)
1777
+ # if we have a regular primary key and it's not set in @values,
1778
+ # we assume it's the last inserted id
1779
+ if (pk = autoincrementing_primary_key) && pk.is_a?(Symbol) && !(vals = @values)[pk]
1780
+ vals[pk] = iid
1781
+ end
1782
+ pk
1783
+ end
1784
+ end
1785
+
1786
+ # The dataset to use when inserting a new object. The same as the model's
1787
+ # dataset by default.
1788
+ def _insert_dataset
1789
+ use_server(model.instance_dataset)
1790
+ end
1791
+
1792
+ # Insert into the given dataset and return the primary key created (if any).
1793
+ def _insert_raw(ds)
1794
+ ds.insert(_insert_values)
1795
+ end
1796
+
1797
+ # Insert into the given dataset and return the hash of column values.
1798
+ def _insert_select_raw(ds)
1799
+ ds.insert_select(_insert_values)
1800
+ end
1801
+
1802
+ # The values hash to use when inserting a new record.
1803
+ alias _insert_values values
1804
+ private :_insert_values
1805
+
1806
+ # Refresh using a particular dataset, used inside save to make sure the same server
1807
+ # is used for reading newly inserted values from the database
1808
+ def _refresh(dataset)
1809
+ _refresh_set_values(_refresh_get(dataset) || raise(NoExistingObject, "Record not found"))
1810
+ _clear_changed_columns(:refresh)
1811
+ end
1812
+
1813
+ # Get the row of column data from the database.
1814
+ def _refresh_get(dataset)
1815
+ if (sql = model.fast_pk_lookup_sql) && !dataset.opts[:lock]
1816
+ sql = sql.dup
1817
+ ds = use_server(dataset)
1818
+ ds.literal_append(sql, pk)
1819
+ ds.with_sql_first(sql)
1820
+ else
1821
+ dataset.first
1822
+ end
1823
+ end
1824
+
1825
+ # Set the values to the given hash after refreshing.
1826
+ def _refresh_set_values(h)
1827
+ @values = h
1828
+ end
1829
+
1830
+ # Internal version of save, split from save to allow running inside
1831
+ # it's own transaction.
1832
+ def _save(opts)
1833
+ pk = nil
1834
+ called_save = false
1835
+ called_cu = false
1836
+ around_save do
1837
+ called_save = true
1838
+ before_save
1839
+
1840
+ if new?
1841
+ around_create do
1842
+ called_cu = true
1843
+ before_create
1844
+ pk = _insert
1845
+ @this = nil
1846
+ @new = false
1847
+ @modified = false
1848
+ pk ? _save_refresh : _clear_changed_columns(:create)
1849
+ after_create
1850
+ true
1851
+ end
1852
+ raise_hook_failure(:around_create) unless called_cu
1853
+ else
1854
+ around_update do
1855
+ called_cu = true
1856
+ before_update
1857
+ columns = opts[:columns]
1858
+ if columns.nil?
1859
+ columns_updated = if opts[:changed]
1860
+ _save_update_changed_colums_hash
1861
+ else
1862
+ _save_update_all_columns_hash
1863
+ end
1864
+ _clear_changed_columns(:update)
1865
+ else # update only the specified columns
1866
+ columns = Array(columns)
1867
+ columns_updated = @values.reject{|k, v| !columns.include?(k)}
1868
+ _changed_columns.reject!{|c| columns.include?(c)}
1869
+ end
1870
+ _update_columns(columns_updated)
1871
+ @this = nil
1872
+ @modified = false
1873
+ after_update
1874
+ true
1875
+ end
1876
+ raise_hook_failure(:around_update) unless called_cu
1877
+ end
1878
+ after_save
1879
+ true
1880
+ end
1881
+ raise_hook_failure(:around_save) unless called_save
1882
+ self
1883
+ end
1884
+
1885
+ # Refresh the object after saving it, used to get
1886
+ # default values of all columns. Separated from _save so it
1887
+ # can be overridden to avoid the refresh.
1888
+ def _save_refresh
1889
+ _save_set_values(_refresh_get(this.server?(:default)) || raise(NoExistingObject, "Record not found"))
1890
+ _clear_changed_columns(:create)
1891
+ end
1892
+
1893
+ # Set values to the provided hash. Called after a create,
1894
+ # to set the full values from the database in the model instance.
1895
+ def _save_set_values(h)
1896
+ @values = h
1897
+ end
1898
+
1899
+ # Return a hash of values used when saving all columns of an
1900
+ # existing object (i.e. not passing specific columns to save
1901
+ # or using update/save_changes). Defaults to all of the
1902
+ # object's values except unmodified primary key columns, as some
1903
+ # databases don't like you setting primary key values even
1904
+ # to their existing values.
1905
+ def _save_update_all_columns_hash
1906
+ v = Hash[@values]
1907
+ cc = changed_columns
1908
+ Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
1909
+ v
1910
+ end
1911
+
1912
+ # Return a hash of values used when saving changed columns of an
1913
+ # existing object. Defaults to all of the objects current values
1914
+ # that are recorded as modified.
1915
+ def _save_update_changed_colums_hash
1916
+ cc = changed_columns
1917
+ @values.reject{|k,v| !cc.include?(k)}
1918
+ end
1919
+
1920
+ # Validate the object if validating on save. Skips validation
1921
+ # completely (including validation hooks) if
1922
+ # skip_validation_on_save! has been called on the object,
1923
+ # resetting the flag so that future saves will validate.
1924
+ def _save_valid?(opts)
1925
+ if @skip_validation_on_next_save
1926
+ @skip_validation_on_next_save = false
1927
+ return true
1928
+ end
1929
+
1930
+ checked_save_failure(opts){_valid?(opts)}
1931
+ end
1932
+
1933
+ # Call _update with the given columns, if any are present.
1934
+ # Plugins can override this method in order to update with
1935
+ # additional columns, even when the column hash is initially empty.
1936
+ def _update_columns(columns)
1937
+ _update(columns) unless columns.empty?
1938
+ end
1939
+
1940
+ # Update this instance's dataset with the supplied column hash,
1941
+ # checking that only a single row was modified.
1942
+ def _update(columns)
1943
+ n = _update_without_checking(columns)
1944
+ raise(NoExistingObject, "Attempt to update object did not result in a single row modification (SQL: #{_update_dataset.update_sql(columns)})") if require_modification && n != 1
1945
+ n
1946
+ end
1947
+
1948
+ # The dataset to use when updating an object. The same as the object's
1949
+ # dataset by default.
1950
+ def _update_dataset
1951
+ this
1952
+ end
1953
+
1954
+ # Update this instances dataset with the supplied column hash.
1955
+ def _update_without_checking(columns)
1956
+ _update_dataset.update(columns)
1957
+ end
1958
+
1959
+ # Whether to use insert_select when inserting a new row.
1960
+ def _use_insert_select?(ds)
1961
+ (!ds.opts[:select] || ds.opts[:returning]) && ds.supports_insert_select?
1962
+ end
1963
+
1964
+ # Internal validation method, running validation hooks.
1965
+ def _valid?(opts)
1966
+ return errors.empty? if frozen?
1967
+ errors.clear
1968
+ called = false
1969
+ skip_validate = opts[:validate] == false
1970
+ around_validation do
1971
+ called = true
1972
+ before_validation
1973
+ validate unless skip_validate
1974
+ after_validation
1975
+ end
1976
+
1977
+ return true if skip_validate
1978
+
1979
+ if called
1980
+ errors.empty?
1981
+ else
1982
+ raise_hook_failure(:around_validation)
1983
+ end
1984
+ end
1985
+
1986
+ # If not raising on failure, check for HookFailed
1987
+ # being raised by yielding and swallow it.
1988
+ def checked_save_failure(opts)
1989
+ if raise_on_failure?(opts)
1990
+ yield
1991
+ else
1992
+ begin
1993
+ yield
1994
+ rescue HookFailed
1995
+ nil
1996
+ end
1997
+ end
1998
+ end
1999
+
2000
+ # If transactions should be used, wrap the yield in a transaction block.
2001
+ def checked_transaction(opts=OPTS, &block)
2002
+ h = {:server=>this_server}.merge!(opts)
2003
+ h[:skip_transaction] = true unless use_transaction?(opts)
2004
+ db.transaction(h, &block)
2005
+ end
2006
+
2007
+ # Change the value of the column to given value, recording the change.
2008
+ def change_column_value(column, value)
2009
+ _add_changed_column(column)
2010
+ @values[column] = value
2011
+ end
2012
+
2013
+ # Default error class used for errors.
2014
+ def errors_class
2015
+ Errors
2016
+ end
2017
+
2018
+ # A HookFailed exception for the given message tied to the current instance.
2019
+ def hook_failed_error(msg)
2020
+ HookFailed.new(msg, self)
2021
+ end
2022
+
2023
+ # Clone constructor -- freeze internal data structures if the original's
2024
+ # are frozen.
2025
+ def initialize_clone(other)
2026
+ super
2027
+ freeze if other.frozen?
2028
+ self
2029
+ end
2030
+
2031
+ # Copy constructor -- Duplicate internal data structures.
2032
+ def initialize_copy(other)
2033
+ super
2034
+ @values = Hash[@values]
2035
+ @changed_columns = @changed_columns.dup if @changed_columns
2036
+ @errors = @errors.dup if @errors
2037
+ self
2038
+ end
2039
+
2040
+ # Set the columns with the given hash. By default, the same as +set+, but
2041
+ # exists so it can be overridden. This is called only for new records, before
2042
+ # changed_columns is cleared.
2043
+ def initialize_set(h)
2044
+ set(h) unless h.empty?
2045
+ end
2046
+
2047
+ # Default inspect output for the inspect, by default, just showing the class.
2048
+ def inspect_prefix
2049
+ model.name
2050
+ end
2051
+
2052
+ # Default inspect output for the values hash, overwrite to change what #inspect displays.
2053
+ def inspect_values
2054
+ @values.inspect
2055
+ end
2056
+
2057
+ # Whether to raise or return false if this action fails. If the
2058
+ # :raise_on_failure option is present in the hash, use that, otherwise,
2059
+ # fallback to the object's raise_on_save_failure (if set), or
2060
+ # class's default (if not).
2061
+ def raise_on_failure?(opts)
2062
+ opts.fetch(:raise_on_failure, raise_on_save_failure)
2063
+ end
2064
+
2065
+ # Raise an error appropriate to the hook type. May be swallowed by
2066
+ # checked_save_failure depending on the raise_on_failure? setting.
2067
+ def raise_hook_failure(type=nil)
2068
+ msg = case type
2069
+ when String
2070
+ type
2071
+ when Symbol
2072
+ "the #{type} hook failed"
2073
+ else
2074
+ "a hook failed"
2075
+ end
2076
+
2077
+ raise hook_failed_error(msg)
2078
+ end
2079
+
2080
+ # Get the ruby class or classes related to the given column's type.
2081
+ def schema_type_class(column)
2082
+ if (sch = db_schema[column]) && (type = sch[:type])
2083
+ db.schema_type_class(type)
2084
+ end
2085
+ end
2086
+
2087
+ # Call setter methods based on keys in hash, with the appropriate values.
2088
+ # Restrict which methods can be called based on the provided type.
2089
+ def set_restricted(hash, type)
2090
+ return self if hash.empty?
2091
+ meths = setter_methods(type)
2092
+ strict = strict_param_setting
2093
+ hash.each do |k,v|
2094
+ k = k.to_s
2095
+ m = "#{k}="
2096
+ if meths.include?(m)
2097
+ set_column_value(m, v)
2098
+ elsif strict
2099
+ # Avoid using respond_to? or creating symbols from user input
2100
+ if public_methods.map(&:to_s).include?(m)
2101
+ if Array(model.primary_key).map(&:to_s).member?(k) && model.restrict_primary_key?
2102
+ raise MassAssignmentRestriction.create("#{k} is a restricted primary key", self, k)
2103
+ else
2104
+ raise MassAssignmentRestriction.create("#{k} is a restricted column", self, k)
2105
+ end
2106
+ else
2107
+ raise MassAssignmentRestriction.create("method #{m} doesn't exist", self, k)
2108
+ end
2109
+ end
2110
+ end
2111
+ self
2112
+ end
2113
+
2114
+ # Returns all methods that can be used for attribute assignment (those that end with =),
2115
+ # depending on the type:
2116
+ #
2117
+ # :default :: Use the default methods allowed in the model class.
2118
+ # :all :: Allow setting all setters, except those specifically restricted (such as ==).
2119
+ # Array :: Only allow setting of columns in the given array.
2120
+ def setter_methods(type)
2121
+ if type == :default && !@singleton_setter_added
2122
+ return model.setter_methods
2123
+ end
2124
+
2125
+ meths = methods.map(&:to_s).select{|l| l.end_with?('=')} - RESTRICTED_SETTER_METHODS
2126
+ meths -= Array(primary_key).map{|x| "#{x}="} if primary_key && model.restrict_primary_key?
2127
+ meths
2128
+ end
2129
+
2130
+ # The server/shard that the model object's dataset uses, or :default if the
2131
+ # model object's dataset does not have an associated shard.
2132
+ def this_server
2133
+ if (s = @server)
2134
+ s
2135
+ elsif (t = @this)
2136
+ t.opts[:server] || :default
2137
+ else
2138
+ model.dataset.opts[:server] || :default
2139
+ end
2140
+ end
2141
+
2142
+ # Typecast the value to the column's type if typecasting. Calls the database's
2143
+ # typecast_value method, so database adapters can override/augment the handling
2144
+ # for database specific column types.
2145
+ def typecast_value(column, value)
2146
+ return value unless typecast_on_assignment && db_schema && (col_schema = db_schema[column])
2147
+ value = nil if '' == value and typecast_empty_string_to_nil and col_schema[:type] and ![:string, :blob].include?(col_schema[:type])
2148
+ raise(InvalidValue, "nil/NULL is not allowed for the #{column} column") if raise_on_typecast_failure && value.nil? && (col_schema[:allow_null] == false)
2149
+ begin
2150
+ model.db.typecast_value(col_schema[:type], value)
2151
+ rescue InvalidValue
2152
+ raise_on_typecast_failure ? raise : value
2153
+ end
2154
+ end
2155
+
2156
+ # Set the columns, filtered by the only and except arrays.
2157
+ def update_restricted(hash, type)
2158
+ set_restricted(hash, type)
2159
+ save_changes
2160
+ end
2161
+
2162
+ # Set the given dataset to use the current object's shard.
2163
+ def use_server(ds)
2164
+ @server ? ds.server(@server) : ds
2165
+ end
2166
+
2167
+ # Whether to use a transaction for this action. If the :transaction
2168
+ # option is present in the hash, use that, otherwise, fallback to the
2169
+ # object's default (if set), or class's default (if not).
2170
+ def use_transaction?(opts = OPTS)
2171
+ opts.fetch(:transaction, use_transactions)
2172
+ end
2173
+
2174
+ # An ValidationFailed exception instance to raise for this instance.
2175
+ def validation_failed_error
2176
+ ValidationFailed.new(self)
2177
+ end
2178
+ end
2179
+
2180
+ # DatasetMethods contains methods that all model datasets have.
2181
+ module DatasetMethods
2182
+ # The model class associated with this dataset
2183
+ #
2184
+ # Artist.dataset.model # => Artist
2185
+ def model
2186
+ @opts[:model]
2187
+ end
2188
+
2189
+ # Assume if a single integer is given that it is a lookup by primary
2190
+ # key, and call with_pk with the argument.
2191
+ #
2192
+ # Artist.dataset[1] # SELECT * FROM artists WHERE (id = 1) LIMIT 1
2193
+ def [](*args)
2194
+ if args.length == 1 && (i = args[0]) && i.is_a?(Integer)
2195
+ with_pk(i)
2196
+ else
2197
+ super
2198
+ end
2199
+ end
2200
+
2201
+ # Destroy each row in the dataset by instantiating it and then calling
2202
+ # destroy on the resulting model object. This isn't as fast as deleting
2203
+ # the dataset, which does a single SQL call, but this runs any destroy
2204
+ # hooks on each object in the dataset.
2205
+ #
2206
+ # Artist.dataset.destroy
2207
+ # # DELETE FROM artists WHERE (id = 1)
2208
+ # # DELETE FROM artists WHERE (id = 2)
2209
+ # # ...
2210
+ def destroy
2211
+ @db.transaction(:server=>opts[:server], :skip_transaction=>model.use_transactions == false) do
2212
+ all(&:destroy).length
2213
+ end
2214
+ end
2215
+
2216
+ # If there is no order already defined on this dataset, order it by
2217
+ # the primary key and call last.
2218
+ #
2219
+ # Album.last
2220
+ # # SELECT * FROM albums ORDER BY id DESC LIMIT 1
2221
+ def last(*a, &block)
2222
+ if ds = _primary_key_order
2223
+ ds.last(*a, &block)
2224
+ else
2225
+ super
2226
+ end
2227
+ end
2228
+
2229
+ # If there is no order already defined on this dataset, order it by
2230
+ # the primary key and call paged_each.
2231
+ #
2232
+ # Album.paged_each{|row| }
2233
+ # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 0
2234
+ # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 1000
2235
+ # # SELECT * FROM albums ORDER BY id LIMIT 1000 OFFSET 2000
2236
+ # # ...
2237
+ def paged_each(*a, &block)
2238
+ if ds = _primary_key_order
2239
+ ds.paged_each(*a, &block)
2240
+ else
2241
+ super
2242
+ end
2243
+ end
2244
+
2245
+ # This allows you to call +as_hash+ without any arguments, which will
2246
+ # result in a hash with the primary key value being the key and the
2247
+ # model object being the value.
2248
+ #
2249
+ # Artist.dataset.as_hash # SELECT * FROM artists
2250
+ # # => {1=>#<Artist {:id=>1, ...}>,
2251
+ # # 2=>#<Artist {:id=>2, ...}>,
2252
+ # # ...}
2253
+ def as_hash(key_column=nil, value_column=nil, opts=OPTS)
2254
+ if key_column
2255
+ super
2256
+ else
2257
+ raise(Sequel::Error, "No primary key for model") unless model && (pk = model.primary_key)
2258
+ super(pk, value_column, opts)
2259
+ end
2260
+ end
2261
+
2262
+ # Alias of as_hash for backwards compatibility.
2263
+ def to_hash(*a)
2264
+ as_hash(*a)
2265
+ end
2266
+
2267
+ # Given a primary key value, return the first record in the dataset with that primary key
2268
+ # value. If no records matches, returns nil.
2269
+ #
2270
+ # # Single primary key
2271
+ # Artist.dataset.with_pk(1)
2272
+ # # SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1
2273
+ #
2274
+ # # Composite primary key
2275
+ # Artist.dataset.with_pk([1, 2])
2276
+ # # SELECT * FROM artists WHERE ((artists.id1 = 1) AND (artists.id2 = 2)) LIMIT 1
2277
+ def with_pk(pk)
2278
+ if pk && (loader = _with_pk_loader)
2279
+ loader.first(*pk)
2280
+ else
2281
+ first(model.qualified_primary_key_hash(pk))
2282
+ end
2283
+ end
2284
+
2285
+ # Same as with_pk, but raises NoMatchingRow instead of returning nil if no
2286
+ # row matches.
2287
+ def with_pk!(pk)
2288
+ with_pk(pk) || raise(NoMatchingRow.new(self))
2289
+ end
2290
+
2291
+ private
2292
+
2293
+ # Return the dataset ordered by the model's primary key. This should not
2294
+ # be used if the model does not have a primary key.
2295
+ def _force_primary_key_order
2296
+ cached_dataset(:_pk_order_ds){order(*unambiguous_primary_key)}
2297
+ end
2298
+
2299
+ # If the dataset is not already ordered, and the model has a primary key,
2300
+ # return a clone ordered by the primary key.
2301
+ def _primary_key_order
2302
+ if @opts[:order].nil? && model && model.primary_key
2303
+ _force_primary_key_order
2304
+ end
2305
+ end
2306
+
2307
+ # A cached placeholder literalizer, if one exists for the current dataset.
2308
+ def _with_pk_loader
2309
+ cached_placeholder_literalizer(:_with_pk_loader) do |pl|
2310
+ table = model.table_name
2311
+ cond = case primary_key = model.primary_key
2312
+ when Array
2313
+ primary_key.map{|key| [SQL::QualifiedIdentifier.new(table, key), pl.arg]}
2314
+ when Symbol
2315
+ {SQL::QualifiedIdentifier.new(table, primary_key)=>pl.arg}
2316
+ else
2317
+ raise(Error, "#{model} does not have a primary key")
2318
+ end
2319
+
2320
+ where(cond).limit(1)
2321
+ end
2322
+ end
2323
+
2324
+ # The primary key for the dataset's model, qualified if the dataset is joined.
2325
+ def unambiguous_primary_key
2326
+ if joined_dataset?
2327
+ model.qualified_primary_key
2328
+ else
2329
+ model.primary_key
2330
+ end
2331
+ end
2332
+
2333
+ def non_sql_option?(key)
2334
+ super || key == :model
2335
+ end
2336
+ end
2337
+
2338
+ extend ClassMethods
2339
+ plugin self
2340
+
2341
+ singleton_class.send(:undef_method, :dup, :clone, :initialize_copy)
2342
+ # :nocov:
2343
+ if RUBY_VERSION >= '1.9.3'
2344
+ # :nocov:
2345
+ singleton_class.send(:undef_method, :initialize_clone, :initialize_dup)
2346
+ end
2347
+
2348
+ # :nocov:
2349
+ if defined?(Sequel::Postgres::SEQUEL_PG_VERSION_INTEGER) && Sequel::Postgres::SEQUEL_PG_VERSION_INTEGER >= 11800
2350
+ # Automatically optimize model loading when sequel/core was loaded,
2351
+ # then sequel/adapters/postgres (with sequel_pg), then sequel/model
2352
+ begin
2353
+ require "sequel_pg/model"
2354
+ rescue LoadError
2355
+ # nothing
2356
+ end
2357
+ end
2358
+ # :nocov:
2359
+ end
2360
+ end