localtower 1.0.0 → 2.0.1

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 (227) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +133 -33
  3. data/app/assets/javascripts/localtower/application.js +30830 -0
  4. data/app/assets/javascripts/localtower/application.js.map +7 -0
  5. data/app/assets/stylesheets/localtower/application.css +1179 -0
  6. data/app/assets/stylesheets/src/application.css +68 -0
  7. data/app/controllers/localtower/pages_controller.rb +20 -35
  8. data/app/javascript/application.js +46 -0
  9. data/app/javascript/components/DarkSelect.js +115 -0
  10. data/app/javascript/components/ModernTooltip.js +26 -0
  11. data/app/javascript/components/NewMigrationForm.js +687 -0
  12. data/app/javascript/components/NewModelForm.js +432 -0
  13. data/app/javascript/components/data/Stores.js +294 -0
  14. data/app/views/layouts/localtower/application.html.erb +80 -66
  15. data/app/views/localtower/_migration.html.erb +30 -0
  16. data/app/views/localtower/pages/_alert_no_models.html.erb +1 -1
  17. data/app/views/localtower/pages/migrations.html.erb +24 -55
  18. data/app/views/localtower/pages/new_migration.html.erb +33 -96
  19. data/app/views/localtower/pages/new_model.html.erb +17 -83
  20. data/config/routes.rb +1 -1
  21. data/lib/localtower/engine.rb +9 -2
  22. data/lib/localtower/generators/migration.rb +218 -91
  23. data/lib/localtower/generators/model.rb +29 -20
  24. data/lib/localtower/generators/service_objects/insert_array.rb +5 -3
  25. data/lib/localtower/generators/service_objects/insert_defaults.rb +73 -3
  26. data/lib/localtower/generators/service_objects/insert_foreign_keys.rb +35 -0
  27. data/lib/localtower/generators/service_objects/insert_indexes.rb +41 -18
  28. data/lib/localtower/generators/service_objects/insert_nullable.rb +5 -3
  29. data/lib/localtower/status.rb +3 -1
  30. data/lib/localtower/tools.rb +20 -9
  31. data/lib/localtower/version.rb +1 -1
  32. data/lib/localtower.rb +0 -6
  33. data/public/com/favicon-64.png +0 -0
  34. data/public/com/twitter-cover-1.png +0 -0
  35. data/public/com/twitter-cover-2.png +0 -0
  36. data/public/fonts/Circular/CircularStd-Black.otf +0 -0
  37. data/public/fonts/Circular/CircularStd-BlackItalic.otf +0 -0
  38. data/public/fonts/Circular/CircularStd-Bold.otf +0 -0
  39. data/public/fonts/Circular/CircularStd-BoldItalic.otf +0 -0
  40. data/public/fonts/Circular/CircularStd-Book.otf +0 -0
  41. data/public/fonts/Circular/CircularStd-BookItalic.otf +0 -0
  42. data/public/fonts/Circular/CircularStd-Light Italic.otf +0 -0
  43. data/public/fonts/Circular/CircularStd-Light.otf +0 -0
  44. data/public/fonts/Circular/CircularStd-Medium.otf +0 -0
  45. data/public/fonts/Circular/CircularStd-MediumItalic.otf +0 -0
  46. data/public/fonts/Circular/Read Me.txt +5 -0
  47. data/public/fonts/Circular/www.dfonts.org.url +2 -0
  48. data/public/screenshots/v0.1.1/1_schema.png +0 -0
  49. data/public/screenshots/v0.1.1/2_models_1.png +0 -0
  50. data/public/screenshots/v0.1.1/2_models_2.png +0 -0
  51. data/public/screenshots/v0.1.1/3_relations.png +0 -0
  52. data/public/screenshots/v0.1.1/4_migrations.png +0 -0
  53. data/public/screenshots/v0.1.6/1_schema.png +0 -0
  54. data/public/screenshots/v0.1.6/2_models_1.png +0 -0
  55. data/public/screenshots/v0.1.6/3_relations.png +0 -0
  56. data/public/screenshots/v0.1.6/4_migrations.png +0 -0
  57. data/public/screenshots/v0.1.6/5_capture.png +0 -0
  58. data/public/screenshots/v1.0.0/migrations.png +0 -0
  59. data/public/screenshots/v1.0.0/models.png +0 -0
  60. data/public/screenshots/v1.0.0/new_migration.png +0 -0
  61. data/public/screenshots/v1.0.0/new_model.png +0 -0
  62. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.30.jpg +0 -0
  63. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.42.jpg +0 -0
  64. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.54.jpg +0 -0
  65. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.21.jpg +0 -0
  66. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.28.jpg +0 -0
  67. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.51.jpg +0 -0
  68. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.49.09.jpg +0 -0
  69. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.04.jpg +0 -0
  70. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.11.jpg +0 -0
  71. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.19.jpg +0 -0
  72. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.47.jpg +0 -0
  73. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.48.jpg +0 -0
  74. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.02.jpg +0 -0
  75. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.18.jpg +0 -0
  76. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.26.jpg +0 -0
  77. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.38.jpg +0 -0
  78. data/public/screenshots/v2.0.0/migrations.png +0 -0
  79. data/public/screenshots/v2.0.0/new_migration.png +0 -0
  80. data/public/screenshots/v2.0.0/new_model.png +0 -0
  81. data/public/vendor/jquery-3.7.1.min.js +2 -0
  82. data/public/vendor/lucide.min.js +12 -0
  83. data/public/vendor/monokai-sublime.css +80 -0
  84. data/public/vendor/rails-ujs.min.js +8 -0
  85. data/spec/dummy/Gemfile +1 -1
  86. data/spec/dummy/Gemfile.lock +146 -104
  87. data/spec/dummy/config/database.yml +4 -6
  88. data/spec/dummy/config/puma.rb +1 -1
  89. data/spec/dummy/db/schema.rb +2 -39
  90. data/spec/dummy/lib/tasks/reset.rake +16 -0
  91. data/spec/dummy/log/development.log +22746 -15994
  92. data/spec/dummy/log/localtower.log +747 -1891
  93. data/spec/dummy/log/test.log +1145 -0
  94. data/spec/dummy/tmp/cache/sessions/localtower/726/FE1/_session_id%3A2%3A%3A69d6764784f832ea25700ea2f242210f3f8d94b48912b0f09ffc44311f0376eb +0 -0
  95. data/spec/dummy/tmp/cache/sessions/localtower/77E/121/_session_id%3A2%3A%3A0b3c1fe7154461ba023ba6c81dd1b999348757880b505f4b082faed263a627f9 +1 -0
  96. data/spec/dummy/tmp/cache/sessions/localtower/7EB/8A1/_session_id%3A2%3A%3Af88237c1d157546a5dcde894fd6c1410162a8eba318748d4ac573ee75e40df16 +0 -0
  97. data/spec/dummy/tmp/local_secret.txt +1 -0
  98. data/spec/factories/migration.rb +77 -40
  99. data/spec/factories/model.rb +46 -26
  100. data/spec/lib/localtower/generators/migration_spec.rb +16 -24
  101. data/spec/lib/localtower/generators/model_spec.rb +71 -8
  102. data/spec/lib/localtower/generators/service_objects/insert_array_spec.rb +1 -1
  103. data/spec/lib/localtower/generators/service_objects/insert_defaults_spec.rb +1 -1
  104. data/spec/lib/localtower/generators/service_objects/insert_foreign_keys_spec.rb +101 -0
  105. data/spec/lib/localtower/generators/service_objects/insert_indexes_spec.rb +1 -1
  106. data/spec/lib/localtower/generators/service_objects/insert_nullable_spec.rb +2 -2
  107. data/spec/spec_helper.rb +2 -3
  108. metadata +107 -238
  109. data/app/views/localtower/pages/models.html.erb +0 -63
  110. data/public/css/app.css +0 -55
  111. data/public/js/app.js +0 -337
  112. data/public/light-bootstrap-dashboard-master/assets/css/animate.min.css +0 -6
  113. data/public/light-bootstrap-dashboard-master/assets/css/bootstrap.min.css +0 -5
  114. data/public/light-bootstrap-dashboard-master/assets/css/demo.css +0 -61
  115. data/public/light-bootstrap-dashboard-master/assets/css/light-bootstrap-dashboard.css +0 -2789
  116. data/public/light-bootstrap-dashboard-master/assets/css/pe-icon-7-stroke.css +0 -632
  117. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.eot +0 -0
  118. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.svg +0 -212
  119. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.ttf +0 -0
  120. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.woff +0 -0
  121. data/public/light-bootstrap-dashboard-master/assets/img/default-avatar.png +0 -0
  122. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-0.jpg +0 -0
  123. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-1.jpg +0 -0
  124. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-2.jpg +0 -0
  125. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-3.jpg +0 -0
  126. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-4.jpg +0 -0
  127. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-5.jpg +0 -0
  128. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-6.jpg +0 -0
  129. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-7.jpg +0 -0
  130. data/public/light-bootstrap-dashboard-master/assets/img/faces/tim_vector.jpe +0 -0
  131. data/public/light-bootstrap-dashboard-master/assets/img/favicon.ico +0 -0
  132. data/public/light-bootstrap-dashboard-master/assets/img/loading-bubbles.svg +0 -14
  133. data/public/light-bootstrap-dashboard-master/assets/img/mask.png +0 -0
  134. data/public/light-bootstrap-dashboard-master/assets/img/new_logo.png +0 -0
  135. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-1.jpg +0 -0
  136. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-2.jpg +0 -0
  137. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-3.jpg +0 -0
  138. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-4.jpg +0 -0
  139. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-5.jpg +0 -0
  140. data/public/light-bootstrap-dashboard-master/assets/img/tim_80x80.png +0 -0
  141. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-checkbox-radio-switch.js +0 -502
  142. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-notify.js +0 -404
  143. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-select.js +0 -438
  144. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap.min.js +0 -7
  145. data/public/light-bootstrap-dashboard-master/assets/js/chartist.min.js +0 -9
  146. data/public/light-bootstrap-dashboard-master/assets/js/demo.js +0 -152
  147. data/public/light-bootstrap-dashboard-master/assets/js/jquery-1.10.2.js +0 -9789
  148. data/public/light-bootstrap-dashboard-master/assets/js/light-bootstrap-dashboard.js +0 -179
  149. data/public/logo-localtower-white-300.png +0 -0
  150. data/public/logo-localtower-white.png +0 -0
  151. data/public/logo-localtower.png +0 -0
  152. data/public/vendor/font-awesome.min.css +0 -4
  153. data/public/vendor/highlight-js-default.min.css +0 -9
  154. data/spec/dummy/app/models/post.rb +0 -3
  155. data/spec/dummy/app/models/user.rb +0 -3
  156. data/spec/dummy/db/migrate/20230119221452_create_users.rb +0 -14
  157. data/spec/dummy/db/migrate/20230119221751_change_users_at1674166670.rb +0 -7
  158. data/spec/dummy/db/migrate/20230119222054_create_posts.rb +0 -11
  159. data/spec/dummy/db/migrate/20230119222106_change_posts_at1674166865.rb +0 -5
  160. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-Y/-YOiiBKqc2UODHFjctm8xc7xFoZaL7zOjWQj6qQ2wyE.cache +0 -1
  161. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-d/-dwueM4vmPt8L51S3jeSyg_AjGDcj0GUN6pDpCA1gCg.cache +0 -3
  162. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0g/0gaJnJQdtd2ACbihXxn8OnjLWlDjnQ_WxfgOpbiLzhg.cache +0 -1
  163. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0r/0rFCsCV9kZnEYtZZ6sfig8329OU31bqjecDFqSVank8.cache +0 -1
  164. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/1J/1J2k_CpnQE3d-PZAQwOVGQALGkta4qVvhdsKjgG0e4Q.cache +0 -0
  165. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2p/2pYVH2Z_syqh6ok8QYxJNKxXpx1Iwppf6JGElZI0gpw.cache +0 -0
  166. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/3W/3WBmqd-2V6q5N-jvbyp-tlcfn3aHYMwBppbOUm7x4qg.cache +0 -1
  167. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/4K/4KFPlHkhdDW0riGUmlbaR-kmDz6JUnQvY6fwW8qsdaE.cache +0 -3
  168. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/6x/6xMeRWmLpNK_flx6-JA3KazvUxSCxyPxHv9Zm3eC26Q.cache +0 -1
  169. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/7d/7dNqI_dCDJLJmI1oM4xwFp9nRRNOem-4P4OD7PMyz2E.cache +0 -0
  170. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/8X/8XquhxVcp5A8QquLtxO8NgKTMJch0eqQmzFmRGIZP6I.cache +0 -1
  171. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ah/AhdfXXtU63kXS4TnsH2Vi1yWgVkIEeV8Z8XA68hrNQc.cache +0 -0
  172. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bt/BtAePnwLSGw82xUGI7wuhWDfuwarOQVS91YqCsweMcs.cache +0 -0
  173. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bx/BxzoG0KxeNLac4xTNeJv3qfeytbNBw58xj2zD-xdbrE.cache +0 -2
  174. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/CC/CCD0ROPX0yxHwNpVZmuP8ZNtgQpaVCMXpdzC0Wb5n24.cache +0 -1
  175. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/DS/DS43oxBg6K5PMWLn2mTy_4EnxI03ehHkxpjV7NCi8yM.cache +0 -1
  176. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Do/Do83AoOat5W-c1g7piDGy2GMmffsY6JY0Qfuh5PY3GM.cache +0 -2
  177. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EI/EI0Nxk-VRATWstMuVCVc0_GdYlQ-a0dx6n2g0l3vIik.cache +0 -0
  178. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EN/ENhJnzJAU2IK-7aHqubj9N8Jo_UTmjG_VEQqyIkolQ8.cache +0 -1
  179. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Fc/FcS6VUHN3Bd4pHGqd5NHA8jA4OLwWrU94s3b4GGxX9c.cache +0 -1
  180. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/G0/G0kukI-r0q0Vbrg6e_jnYJoYcOX8K__h-mwKbCf4twE.cache +0 -0
  181. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/I1/I1Jw08-mz8xzgrgi6giCzpf1UmzGTSbl4eJEw4DAoJM.cache +0 -1
  182. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/IV/IVOO1dXBmgjieDk__g57p6aYt0Z3CmfTa32jhegoyko.cache +0 -3
  183. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/JY/JYPmv5WP4wxdI9EKEEPkK_fVtqeSLfmint_5E8fQLQ8.cache +0 -1
  184. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/MX/MXI3KxaQPZGImSvCNZ_TbQVruWCJ3E0xiVxza1ZCAjM.cache +0 -1
  185. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/OU/OUoioCqXALK909jXPV3VSyCJIdNC7bsogUfdnRTpc5o.cache +0 -1
  186. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/PH/PHjtqNLUPAUDiSlu5AbPjlIo20mOGNm0uNjMLhX2NvM.cache +0 -0
  187. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RC/RC9vfALY5K634pTeau0BAhTHl7d5_5yA3tM-QTLiKtI.cache +0 -0
  188. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RG/RG1PrmlixwaUlG8BV0kcm_3F7OQekxsrLYjBdf403-k.cache +0 -2
  189. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ut/UtoMO6n6FHTpRCGk9VfxlfTI2Ao2GYJ_6kMzx3B9VH8.cache +0 -1
  190. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/VE/VExnbpDk3LxYdPk3htUrZQXPI8NK_zlKtSFfVXJlxU4.cache +0 -1
  191. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wm/WmKTjykiU-Tx_Faf5zduEeEQ-DozAs5omKToM2l1cZM.cache +0 -0
  192. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/X-/X-KjhDPd0nI155N_FaxFSgaOiYo0_ytqlmkBlLM7ayw.cache +0 -1
  193. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/XX/XXVhj-O91tJ5c8pz7DQlTABOv8TIRVg5haw9VOq9HuI.cache +0 -1
  194. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/YC/YCiifo5NCMwDChFqYFiV4EaYEx8hy3Efle1PsGbIdak.cache +0 -1
  195. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ya/YayMISAqD-Y3vBFywwKrXbUovGf5o77HUF5s8mnQgO0.cache +0 -0
  196. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Zl/Zl-NEb0aDLmZ9gN4gdY1OYlbUXD4JhkFY_y23m55zmo.cache +0 -0
  197. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_h/_hnjPptBeD3GP5B0iJR6pvyVkiMiq-o2TxaYmGf9KJo.cache +0 -3
  198. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_p/_poEF6QbTPYJiQCFGoXxIXjmvcn6T0I87ElzJGHguk0.cache +0 -1
  199. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/aa/aaSj2zt8ddc87nZqTpOI9gRCKVnoalXKFBww7t4t3Kg.cache +0 -0
  200. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/bZ/bZHWUkrOLp0WM_Ogo36Qjt4cxDt-rOFgtcj4LNB-BVE.cache +0 -1
  201. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cP/cPSNG_663TNT944Rke919luRS6FtpMwVc_7aDph645w.cache +0 -1
  202. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ce/ceq8fcZGIoqWrCl9vrCRrywEdx42iy9PrGG9CwFSIF4.cache +0 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cl/cljhP0Jc018nLnG1rpdg-FUf6mlIqrQYvXTNXTNG9Bw.cache +0 -0
  204. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dm/dmod3fTZdoKso2FGM5RTQtb4kTB6vywsiXLWDygYFN4.cache +0 -1
  205. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dy/dySDGcUTqlKx2MTvOmIEP-WzhyhCfU5xhN9qgxbz3rI.cache +0 -0
  206. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gQ/gQYdmEzbLjTcFCnsfzXzEmeminOchF263snAk3IvXM0.cache +0 -1
  207. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gh/ghvuMAqccBGljlmEaI3Gt5tH5rEg6hseKYMYfRMkHdY.cache +0 -1
  208. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gt/gt8QC7k92A4hXA3HlCpQulW73tqd6x63I3uT-YrGMj0.cache +0 -1
  209. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/hf/hfVg-y7dPSQKbb7V3I7M5w7IpOhDiIB2H31d2tmbZMU.cache +0 -0
  210. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/iF/iFLwyhZIu1Jxm77NUT2qWeTDMmyELW4U85t9rGE_KVg.cache +0 -0
  211. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/kF/kFlIcBBnSyKE00OjpM90pqSn93mLMUv9esz86nrO-Cs.cache +0 -1
  212. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/MazNt_5OaYexRuZnccZZ_7AONlxn1a4W3KdWyHyBdws.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/ma3w08gnDTeqwY2-C9BlToxA6-AS8bvXlu-nBiz0UYs.cache +0 -1
  214. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/n_/n_xYqQYhwEMQknb3jFQnjlxxBE9TzMNHCdJ-bEyZFIw.cache +0 -2
  215. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/nx/nxTv3sKVUQZADJyM3dPaVmUA78MIsMLD_K279yN_GsI.cache +0 -2
  216. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/pv/pv6tV3CDkIAmLXdU8EPLlNEkXAKJPufVD4VP30o4fWo.cache +0 -0
  217. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/qP/qPmv5snMrDw830S6hSICDcnIy7kVEWoFKXhGKT38lG4.cache +0 -2
  218. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/sY/sYvTb1uPWWmnHJNXKuW_xSco-aUb-rN2f0J35zSIzuc.cache +0 -1
  219. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/su/suQ_jjDxRiIn4VEqFJYKaBWJILaeGKBvoTv49XNX0vo.cache +0 -1
  220. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/u8/u8IrW5IIQ7espwk2Vpk23zheL9YZA0tnbKq9X7E-WA0.cache +0 -1
  221. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/wh/whzETExjcZCkn4msasD2aylgfhfpKPZrNxTkY-SOIDg.cache +0 -2
  222. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/x7/x7PYh8DJvPykcEqpVab2vcY9-GFz-3cqtoMlRAu94Uc.cache +0 -2
  223. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/y6/y6oxsJD3pAY9ph1_5M-77uiEjTVw8BheLZNygCKPm1g.cache +0 -1
  224. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/yH/yHZ-a1J23ZCf2n5mEHINMz23Iec2cLGTKauW7k4yGTE.cache +0 -0
  225. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/z7/z7KfUWYoSaGq8tQ5mbHwyfXyT3Pa4FWKJswHcIdJuds.cache +0 -1
  226. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/zu/zuExWc5WHxeOUPZUKHl9a9ZRmN50g7jMOD28macn6M0.cache +0 -0
  227. data/spec/dummy/tmp/pids/server.pid +0 -1
@@ -1,18 +1,28 @@
1
+ #
2
+ # @see https://github.com/rails/rails/blob/main/activerecord/lib/active_record/migration.rb
3
+ # @see https://github.com/rails/rails/blob/main/activerecord/lib/active_record/migration/command_recorder.rb
4
+ # @see https://api.rubyonrails.org/v7.2.1/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html
5
+ #
1
6
  module Localtower
2
7
  module Generators
3
8
  class ThorGeneratorMigration < Thor
9
+ SPACE_PADDING = " "
10
+
4
11
  include Thor::Base
5
12
  include Thor::Actions
6
13
 
7
14
  no_commands do
8
15
  def migration_add_column(data)
16
+ raise "No table name provided" if data['table_name'].blank?
17
+ raise "No attribute name provided" if data['column_name'].blank?
18
+
9
19
  # Special case for array
10
20
  if %w[array].include?(data["column_type"])
11
- line = " add_column :#{data['table_name']}, :#{data['column']}, :string"
12
- line << ", default: []"
21
+ line = "#{SPACE_PADDING}add_column :#{data['table_name']}, :#{data['column_name']}, :string"
22
+ line << ", default: #{data['default']}" if data['default'].present?
13
23
  line << ", array: true"
14
24
  else
15
- line = " add_column :#{data['table_name']}, :#{data['column']}, :#{data['column_type']}"
25
+ line = "#{SPACE_PADDING}add_column :#{data['table_name']}, :#{data['column_name']}, :#{data['column_type']}"
16
26
  line << ", default: #{data['default']}" if data['default'].present?
17
27
  line << ", null: false" if data['nullable'] == false
18
28
  end
@@ -20,71 +30,86 @@ module Localtower
20
30
  line << "\n"
21
31
 
22
32
  inject_in_migration(file, line)
33
+
34
+ if data["index"].present?
35
+ migration_add_index_to_column(data)
36
+ end
23
37
  end
24
38
 
25
39
  def migration_remove_column(data)
26
- line = " remove_column :#{data['table_name']}, :#{data['column']}\n"
40
+ raise "No table name provided" if data['table_name'].blank?
41
+ raise "No attribute name provided" if data['column_name'].blank?
42
+
43
+ line = "#{SPACE_PADDING}remove_column :#{data['table_name']}, :#{data['column_name']}\n"
27
44
 
28
45
  inject_in_migration(file, line)
29
46
  end
30
47
 
31
48
  def migration_rename_column(data)
32
- line = " rename_column :#{data['table_name']}, :#{data['column']}, :#{data['new_column_name']}\n"
49
+ raise "No table name provided" if data['table_name'].blank?
50
+ raise "No attribute name provided" if data['column_name'].blank?
51
+ raise "No new attribute name provided" if data['new_column_name'].blank?
52
+
53
+ line = "#{SPACE_PADDING}rename_column :#{data['table_name']}, :#{data['column_name']}, :#{data['new_column_name']}\n"
33
54
 
34
55
  inject_in_migration(file, line)
35
56
  end
36
57
 
37
58
  def migration_change_column_type(data)
38
- line = " change_column :#{data['table_name']}, :#{data['column']}, :#{data['new_column_type']}\n"
59
+ raise "No table name provided" if data['table_name'].blank?
60
+ raise "No attribute name provided" if data['column_name'].blank?
61
+ raise "No new attribute type provided" if data['new_column_type'].blank?
62
+
63
+ line = "#{SPACE_PADDING}change_column :#{data['table_name']}, :#{data['column_name']}, :#{data['new_column_type']}\n"
39
64
 
40
65
  inject_in_migration(file, line)
41
66
  end
42
67
 
43
68
  def migration_add_index_to_column(data)
44
- line = " add_index :#{data['table_name']}, :#{data['column']}\n"
69
+ raise "No table name provided" if data['table_name'].blank?
70
+ raise "No attribute name provided" if data['column_name'].blank?
71
+ raise "No index provided" if data['index'].blank?
72
+
73
+ line = "#{SPACE_PADDING}add_index :#{data['table_name']}, :#{data['column_name']}\n"
45
74
 
46
75
  inject_in_migration(file, line)
47
76
 
48
77
  # Custom options:
49
78
  params = [data]
50
- .select { |attr| attr.dig('index', 'using').present? }
51
- .reject { |attr| attr.dig('index', 'using') == 'none' }
52
- .each_with_object([]) do |attr, arr|
53
- arr << Hash[attr['column'], attr['index']]
79
+ .select { |attr| attr["index"].present? }
80
+ .each_with_object([]) do |attr, arr|
81
+ arr << Hash[attr['column_name'],
82
+ { "using" => attr['index'], "algorithm" => attr['index_algorithm'], "unique" => attr['unique'] }]
54
83
  end
55
84
  ::Localtower::Generators::ServiceObjects::InsertIndexes.new(params).call
56
85
  end
57
86
 
58
87
  def migration_remove_index_to_column(data)
59
- line = " remove_index :#{data['table_name']}, :#{data['column']}\n"
88
+ raise "No table name provided" if data['table_name'].blank?
89
+ raise "No index_name provided" if data['index_name'].blank?
90
+
91
+ line = "#{SPACE_PADDING}remove_index :#{data['table_name']}, name: :#{data['index_name']}\n"
60
92
 
61
93
  inject_in_migration(file, line)
62
94
  end
63
95
 
64
96
  def migration_belongs_to(data)
65
- line = " add_reference :#{data['table_name']}, :#{data['column']}, foreign_key: true, index: true\n"
97
+ raise "No table name provided" if data['table_name'].blank?
98
+ raise "No attribute name provided" if data['column_name'].blank?
66
99
 
67
- inject_in_migration(file, line)
68
-
69
- file = "#{Rails.root}/app/models/#{data['table_name'].underscore.singularize}.rb"
70
- after = /class #{data["table_name"].camelize.singularize} < ApplicationRecord\n/
71
- line1 = " # belongs_to :#{data['column'].singularize.underscore}\n"
100
+ line = "#{SPACE_PADDING}add_reference :#{data['table_name']}, :#{data['column_name']}"
72
101
 
73
- if File.exist?(file)
74
- ::Localtower::Tools::ThorTools.new.insert_after_word(file, after, line1)
75
- end
76
-
77
- file = "#{Rails.root}/app/models/#{data['column'].underscore.singularize}.rb"
78
- after = /class #{data["column"].camelize.singularize} < ApplicationRecord\n/
79
- line1 = " # has_many :#{data['table_name'].pluralize.underscore}\n"
102
+ line << ", foreign_key: true" if data['foreign_key'].present?
103
+ line << ", index: true"
104
+ line << "\n"
80
105
 
81
- if File.exist?(file)
82
- ::Localtower::Tools::ThorTools.new.insert_after_word(file, after, line1)
83
- end
106
+ inject_in_migration(file, line)
84
107
  end
85
108
 
86
109
  def migration_drop_table(data)
87
- line = " drop_table :#{data['table_name']}\n"
110
+ raise "No table name provided" if data['table_name'].blank?
111
+
112
+ line = "#{SPACE_PADDING}drop_table :#{data['table_name']}\n"
88
113
 
89
114
  inject_in_migration(file, line)
90
115
  end
@@ -96,90 +121,192 @@ module Localtower
96
121
  end
97
122
 
98
123
  def file
99
- Localtower::Tools.last_migration
124
+ Localtower::Tools.last_migration_pending
100
125
  end
101
126
  end
102
127
  end
103
128
 
104
129
  class Migration
105
- TYPES = %w[string datetime date text uuid integer float json jsonb decimal binary boolean array references].freeze
106
- ACTIONS = %w[
107
- add_column
108
- add_index_to_column
109
- remove_index_to_column
110
- belongs_to
111
- remove_column
112
- change_column_type
113
- rename_column
114
- drop_table
115
- ].freeze
130
+ TYPES = [
131
+ {
132
+ name: "string",
133
+ example: "'foo'",
134
+ },
135
+ {
136
+ name: "text",
137
+ example: "'long foo'",
138
+ },
139
+ {
140
+ name: "datetime",
141
+ example: "2024-07-22 12:28:31.487318",
142
+ },
143
+ {
144
+ name: "date",
145
+ example: "2024-09-24",
146
+ },
147
+ {
148
+ name: "uuid",
149
+ example: "'860f5e00-0000-0000-0000-000000000000'",
150
+ },
151
+ {
152
+ name: "integer",
153
+ example: "123",
154
+ },
155
+ {
156
+ name: "bigint",
157
+ example: "123",
158
+ },
159
+ {
160
+ name: "float",
161
+ example: "30.12",
162
+ },
163
+ {
164
+ name: "numeric",
165
+ example: "30.12",
166
+ },
167
+ {
168
+ name: "decimal",
169
+ example: "30.12",
170
+ },
171
+ {
172
+ name: "json",
173
+ example: "{\"foo\": \"bar\"}",
174
+ },
175
+ {
176
+ name: "jsonb",
177
+ example: "{\"foo\": \"bar\"}",
178
+ },
179
+ {
180
+ name: "binary",
181
+ example: "01010001",
182
+ },
183
+ {
184
+ name: "boolean",
185
+ example: "true/false",
186
+ },
187
+ {
188
+ name: "array",
189
+ example: "[1, 2, 3]",
190
+ },
191
+ {
192
+ name: "blob",
193
+ example: "x3F7F2A9",
194
+ },
195
+ {
196
+ name: "references",
197
+ example: "MyModel",
198
+ }
199
+ ]
200
+
201
+ ACTIONS = [
202
+ {
203
+ name: "add_column",
204
+ label: "Add column",
205
+ example: "add_column :users, :name, :string",
206
+ },
207
+ {
208
+ name: "add_index_to_column",
209
+ label: "Add index",
210
+ example: "add_index :users, :name",
211
+ },
212
+ {
213
+ name: "belongs_to",
214
+ label: "Add reference",
215
+ example: "add_reference :posts, :user",
216
+ },
217
+ {
218
+ name: "remove_index_to_column",
219
+ label: "Remove index",
220
+ example: "remove_index :users, :name",
221
+ },
222
+ {
223
+ name: "remove_column",
224
+ label: "Remove column",
225
+ example: "remove_column :users, :name",
226
+ },
227
+ {
228
+ name: "change_column_type",
229
+ label: "Change column type",
230
+ example: "change_column :users, :name, :string",
231
+ },
232
+ {
233
+ name: "rename_column",
234
+ label: "Rename column",
235
+ example: "rename_column :users, :name, :new_name",
236
+ },
237
+ {
238
+ name: "drop_table",
239
+ label: "Drop table",
240
+ example: "drop_table :users",
241
+ }
242
+ ]
116
243
 
117
244
  # @opts =
118
- def initialize(migrations)
245
+ def initialize(migrations, migration_name = nil)
119
246
  @thor = ThorGeneratorMigration.new
247
+
248
+ # stringify keys:
120
249
  @migrations = JSON[migrations.to_json]
250
+ @migration_name = migration_name
121
251
  end
122
252
 
253
+ # const DEFAULT_LINE = {
254
+ # model_name: MODELS[0] ? MODELS[0].value : '',
255
+ # table_name: MODELS[0] ? MODELS[0].table_name : '',
256
+ # action_name: 'add_column',
257
+ # column_type: 'string',
258
+ # column_name: '',
259
+ # new_column_name: '',
260
+ # new_column_type: '',
261
+ # default: '',
262
+ # unique: false,
263
+ # foreign_key: false,
264
+ # index: '',
265
+ # index_algorithm: 'default',
266
+ # index_name: '',
267
+ # nullable: true
268
+ # };
269
+
123
270
  def run
124
- model_names = migrations.map { |line| line['table_name'].camelize }.uniq.join
271
+ if Localtower::Tools.pending_migrations.any?
272
+ # raise "There is a pending migration. You can't generate a migration until the pending migration is committed."
273
+ else
274
+ migration_name_final = if @migration_name.present?
275
+ @migration_name
276
+ else
277
+ action_names = migrations.map { |line| line['action_name'].camelize }.uniq.take(1).join
278
+ model_names = migrations.map { |line| line['model_name'].camelize }.uniq.take(2).join
279
+ column_names = migrations.map { |line| (line['column_name'].presence || "").camelize }.uniq.take(2).join
125
280
 
126
- cmd = "Change#{model_names}At#{Time.now.to_i}"
127
- ::Localtower::Tools.perform_migration(cmd)
281
+ "#{action_names}#{column_names}For#{model_names}"
282
+ end
128
283
 
129
- migrations.each do |action_line|
130
- next if action_line['action'].blank?
131
-
132
- {
133
- 'add_column' => -> { add_column(action_line) },
134
- 'remove_column' => -> { remove_column(action_line) },
135
- 'rename_column' => -> { rename_column(action_line) },
136
- 'change_column_type' => -> { change_column_type(action_line) },
137
- 'add_index_to_column' => -> { add_index_to_column(action_line) },
138
- 'belongs_to' => -> { belongs_to(action_line) },
139
- 'remove_index_to_column' => -> { remove_index_to_column(action_line) },
140
- 'drop_table' => -> { drop_table(action_line) }
141
- }[action_line['action']].call
284
+ ::Localtower::Tools.perform_migration(migration_name_final)
142
285
  end
143
- end
144
286
 
145
- private
146
-
147
- attr_reader :migrations
148
-
149
- def add_column(data)
150
- @thor.migration_add_column(data)
151
- end
152
-
153
- def remove_column(data)
154
- @thor.migration_remove_column(data)
155
- end
287
+ migrations.each do |action_line|
288
+ next if action_line['action_name'].blank?
156
289
 
157
- def rename_column(data)
158
- @thor.migration_rename_column(data)
159
- end
290
+ # action_line['table_name'] = action_line['model_name'].pluralize.underscore
160
291
 
161
- def change_column_type(data)
162
- @thor.migration_change_column_type(data)
163
- end
164
-
165
- def add_index_to_column(data)
166
- @thor.migration_add_index_to_column(data)
167
- end
292
+ proc_var = {
293
+ 'add_column' => -> { thor.migration_add_column(action_line) },
294
+ 'remove_column' => -> { thor.migration_remove_column(action_line) },
295
+ 'rename_column' => -> { thor.migration_rename_column(action_line) },
296
+ 'change_column_type' => -> { thor.migration_change_column_type(action_line) },
297
+ 'add_index_to_column' => -> { thor.migration_add_index_to_column(action_line) },
298
+ 'belongs_to' => -> { thor.migration_belongs_to(action_line) },
299
+ 'remove_index_to_column' => -> { thor.migration_remove_index_to_column(action_line) },
300
+ 'drop_table' => -> { thor.migration_drop_table(action_line) }
301
+ }[action_line['action_name']]
168
302
 
169
- def belongs_to(data)
170
- data["column"] = data["belongs_to"].underscore.singularize
171
- data['column_type'] = "references"
303
+ raise "No proc found for action_name #{action_line['action_name']}" unless proc_var
172
304
 
173
- @thor.migration_belongs_to(data)
174
- end
175
-
176
- def remove_index_to_column(data)
177
- @thor.migration_remove_index_to_column(data)
305
+ proc_var.call
306
+ end
178
307
  end
179
308
 
180
- def drop_table(data)
181
- @thor.migration_drop_table(data)
182
- end
309
+ attr_reader :thor, :migrations
183
310
  end
184
311
  end
185
312
  end
@@ -12,45 +12,44 @@ module Localtower
12
12
 
13
13
  def run
14
14
  attributes_str = parse_attributes.join(" ")
15
- cmd = "rails generate model #{model_name.camelize} #{attributes_str}"
16
-
15
+ cmd = "rails generate model #{model_name.camelize} #{attributes_str} --force"
17
16
  ::Localtower::Tools.perform_cmd(cmd)
18
17
 
19
18
  insert_non_nullable_values
20
19
  insert_default_values
21
20
  insert_array
22
21
  insert_indexes
22
+ insert_foreign_keys
23
23
  end
24
24
 
25
25
  private
26
26
 
27
- attr_reader :model_name
28
- attr_reader :attributes
27
+ attr_reader :model_name, :attributes
29
28
 
30
29
  def parse_attributes
31
30
  attributes.map do |attr_hash|
32
31
  [
33
- attr_hash['attribute_name'],
34
- (attr_hash['attribute_type'] == 'array' ? 'string' : attr_hash['attribute_type']), # we need this transformation of "array"
35
- (attr_hash.dig('index', 'using') != 'none') ? 'index' : nil
32
+ attr_hash['column_name'],
33
+ # we need this transformation of "array":
34
+ (attr_hash['column_type'] == 'array' ? 'string' : attr_hash['column_type']),
35
+ attr_hash["index"].present? ? 'index' : nil
36
36
  ].compact.join(':')
37
37
  end
38
38
  end
39
39
 
40
40
  def insert_array
41
41
  params = attributes
42
- .select { |attr| attr['attribute_type'] == 'array' }
43
- .map { |attr| attr['attribute_name'] }
42
+ .select { |attr| attr['column_type'] == 'array' }
43
+ .map { |attr| attr['column_name'] }
44
44
 
45
45
  Localtower::Generators::ServiceObjects::InsertArray.new(params).call
46
46
  end
47
47
 
48
48
  def insert_default_values
49
49
  params = attributes
50
- .reject { |attr| attr['default'] == nil }
51
- .reject { |attr| attr['default'] == '' }
52
- .each_with_object([]) do |attr, arr|
53
- arr << Hash[attr['attribute_name'], attr['default']]
50
+ .select { |attr| attr['default'].present? }
51
+ .each_with_object([]) do |attr, arr|
52
+ arr << Hash[attr['column_name'], attr['default']]
54
53
  end
55
54
 
56
55
  Localtower::Generators::ServiceObjects::InsertDefaults.new(params).call
@@ -58,22 +57,32 @@ module Localtower
58
57
 
59
58
  def insert_non_nullable_values
60
59
  params = attributes
61
- .select { |attr| attr['nullable'] == false }
62
- .map{ |attr| attr['attribute_name'] }
60
+ .select { |attr| attr['nullable'] == false }
61
+ .map { |attr| attr['column_name'] }
63
62
 
64
63
  ::Localtower::Generators::ServiceObjects::InsertNullable.new(params).call
65
64
  end
66
65
 
67
66
  def insert_indexes
68
67
  params = attributes
69
- .select { |attr| attr.dig('index', 'using').present? }
70
- .reject { |attr| attr.dig('index', 'using') == 'none' }
71
- .each_with_object([]) do |attr, arr|
72
- arr << Hash[attr['attribute_name'], attr['index']]
73
- end
68
+ .select { |attr| attr["index"].present? }
69
+ .each_with_object([]) do |attr, arr|
70
+ arr << Hash[attr['column_name'],
71
+ { "using" => attr['index'], "algorithm" => attr['index_algorithm'], "unique" => attr['unique'] }]
72
+ end
74
73
 
75
74
  ::Localtower::Generators::ServiceObjects::InsertIndexes.new(params).call
76
75
  end
76
+
77
+ def insert_foreign_keys
78
+ params = attributes
79
+ .each_with_object([]) do |attr, arr|
80
+ arr << Hash[attr['column_name'],
81
+ { "foreign_key" => attr['foreign_key'] }]
82
+ end
83
+
84
+ ::Localtower::Generators::ServiceObjects::InsertForeignKeys.new(params).call
85
+ end
77
86
  end
78
87
  end
79
88
  end
@@ -8,9 +8,11 @@ module Localtower
8
8
 
9
9
  def call
10
10
  attributes.each do |attribute|
11
- line_str = File.read(Localtower::Tools.last_migration).match(/((.*)t\.string :#{attribute})/)[0]
12
- content = File.read(Localtower::Tools.last_migration).gsub(line_str, "#{line_str}, array: true")
13
- File.write(Localtower::Tools.last_migration, content)
11
+ line_str = Localtower::Tools.line_for_attribute(attribute)[0]
12
+ if line_str.present?
13
+ content = File.read(Localtower::Tools.last_migration_pending).gsub(line_str, "#{line_str}, array: true")
14
+ File.write(Localtower::Tools.last_migration_pending, content)
15
+ end
14
16
  end
15
17
  end
16
18
 
@@ -13,6 +13,74 @@ module Localtower
13
13
  'nil' => 'nil',
14
14
  }
15
15
 
16
+ DEFAULT_VALUES = {
17
+ 'NULL' => { value: '', label: 'NULL', example: 'NULL' },
18
+ 'EMPTY_STRING' => { value: "''", label: 'Empty string', example: "''" },
19
+ 'NOW_DATETIME' => { value: "'now()'", label: 'Current datetime', example: 'now()' },
20
+ 'NOW_DATE' => { value: "'now()'", label: 'Current date', example: 'now()' },
21
+ 'ZERO' => { value: "0", label: 'Zero', example: '0' },
22
+ 'JSON' => { value: "{}", label: 'Empty JSON', example: '{}' }
23
+ }
24
+
25
+ DEFAULTS_BY_TYPE = {
26
+ string: [
27
+ DEFAULT_VALUES['NULL'],
28
+ DEFAULT_VALUES['EMPTY_STRING']
29
+ ],
30
+ text: [
31
+ DEFAULT_VALUES['NULL'],
32
+ DEFAULT_VALUES['EMPTY_STRING']
33
+ ],
34
+ datetime: [
35
+ DEFAULT_VALUES['NULL'],
36
+ DEFAULT_VALUES['NOW_DATETIME']
37
+ ],
38
+ date: [
39
+ DEFAULT_VALUES['NULL'],
40
+ DEFAULT_VALUES['NOW_DATE']
41
+ ],
42
+ uuid: [
43
+ DEFAULT_VALUES['NULL']
44
+ ],
45
+ integer: [
46
+ DEFAULT_VALUES['NULL'],
47
+ DEFAULT_VALUES['ZERO']
48
+ ],
49
+ bigint: [
50
+ DEFAULT_VALUES['NULL'],
51
+ DEFAULT_VALUES['ZERO']
52
+ ],
53
+ float: [
54
+ DEFAULT_VALUES['NULL'],
55
+ DEFAULT_VALUES['ZERO']
56
+ ],
57
+ numeric: [
58
+ DEFAULT_VALUES['NULL'],
59
+ DEFAULT_VALUES['ZERO']
60
+ ],
61
+ decimal: [
62
+ DEFAULT_VALUES['NULL'],
63
+ DEFAULT_VALUES['ZERO']
64
+ ],
65
+ json: [
66
+ DEFAULT_VALUES['NULL'],
67
+ DEFAULT_VALUES['JSON']
68
+ ],
69
+ jsonb: [
70
+ DEFAULT_VALUES['NULL'],
71
+ DEFAULT_VALUES['JSON']
72
+ ],
73
+ boolean: [
74
+ DEFAULT_VALUES['NULL'],
75
+ { value: 'true', label: 'True', example: 'true' },
76
+ { value: 'false', label: 'False', example: 'false' }
77
+ ],
78
+ array: [
79
+ DEFAULT_VALUES['NULL'],
80
+ { value: '[]', label: 'Empty array', example: '[]' }
81
+ ]
82
+ }
83
+
16
84
  def initialize(attributes)
17
85
  @attributes = attributes
18
86
  end
@@ -20,9 +88,11 @@ module Localtower
20
88
  def call
21
89
  attributes.each do |attribute|
22
90
  attribute.each do |attr_key, attr_value|
23
- line_str = File.read(Localtower::Tools.last_migration).match(/((.*)t\.(.*)\:#{attr_key})/)[0]
24
- content = File.read(Localtower::Tools.last_migration).gsub(line_str, "#{line_str}, default: #{attr_value}")
25
- File.write(Localtower::Tools.last_migration, content)
91
+ line_str = Localtower::Tools.line_for_attribute(attr_key)[0]
92
+ if line_str.present?
93
+ content = File.read(Localtower::Tools.last_migration_pending).gsub(line_str, "#{line_str}, default: #{attr_value}")
94
+ File.write(Localtower::Tools.last_migration_pending, content)
95
+ end
26
96
  end
27
97
  end
28
98
  end
@@ -0,0 +1,35 @@
1
+ module Localtower
2
+ module Generators
3
+ module ServiceObjects
4
+ class InsertForeignKeys
5
+ def initialize(attributes)
6
+ @attributes = attributes
7
+ end
8
+
9
+ def call
10
+ attributes.each do |attribute|
11
+ attribute.each do |attr_key, options|
12
+ line_str = Localtower::Tools.line_for_attribute(attr_key)[0]
13
+ if line_str.present?
14
+ if options['foreign_key'].present?
15
+ if line_str['foreign_key: true']
16
+ content = File.read(Localtower::Tools.last_migration_pending)
17
+ else
18
+ content = File.read(Localtower::Tools.last_migration_pending).gsub(line_str, "#{line_str}, foreign_key: true")
19
+ end
20
+ else
21
+ content = File.read(Localtower::Tools.last_migration_pending).gsub(line_str, line_str.gsub(', foreign_key: true', ''))
22
+ end
23
+ File.write(Localtower::Tools.last_migration_pending, content)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :attributes
32
+ end
33
+ end
34
+ end
35
+ end