ezii-postgres 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/ezii-postgres.gemspec +13 -0
  3. data/natural-backend/Capfile +50 -0
  4. data/natural-backend/Gemfile +63 -0
  5. data/natural-backend/Gemfile.lock +233 -0
  6. data/natural-backend/LICENSE +21 -0
  7. data/natural-backend/Procfile +2 -0
  8. data/natural-backend/README.md +51 -0
  9. data/natural-backend/Rakefile +6 -0
  10. data/natural-backend/app.json +28 -0
  11. data/natural-backend/app/channels/application_cable/channel.rb +4 -0
  12. data/natural-backend/app/channels/application_cable/connection.rb +4 -0
  13. data/natural-backend/app/commands/base_command.rb +31 -0
  14. data/natural-backend/app/commands/create_new_or_authenticate_user.rb +60 -0
  15. data/natural-backend/app/commands/create_project_authentication_token_command.rb +25 -0
  16. data/natural-backend/app/commands/decode_authentication_command.rb +50 -0
  17. data/natural-backend/app/commands/decode_project_authentication_token_command.rb +51 -0
  18. data/natural-backend/app/controllers/application_controller.rb +3 -0
  19. data/natural-backend/app/controllers/authentication_controller.rb +17 -0
  20. data/natural-backend/app/controllers/columns_controller.rb +51 -0
  21. data/natural-backend/app/controllers/concerns/token_authenticatable.rb +26 -0
  22. data/natural-backend/app/controllers/databases_controller.rb +51 -0
  23. data/natural-backend/app/controllers/ember_controller.rb +6 -0
  24. data/natural-backend/app/controllers/projects_controller.rb +51 -0
  25. data/natural-backend/app/controllers/queries_controller.rb +59 -0
  26. data/natural-backend/app/controllers/row_values_controller.rb +51 -0
  27. data/natural-backend/app/controllers/rows_controller.rb +56 -0
  28. data/natural-backend/app/controllers/tables_controller.rb +55 -0
  29. data/natural-backend/app/jobs/application_job.rb +2 -0
  30. data/natural-backend/app/jobs/create_column_job.rb +10 -0
  31. data/natural-backend/app/jobs/create_database_job.rb +11 -0
  32. data/natural-backend/app/jobs/create_database_user_job.rb +8 -0
  33. data/natural-backend/app/jobs/create_table_job.rb +21 -0
  34. data/natural-backend/app/jobs/delete_row_job.rb +12 -0
  35. data/natural-backend/app/jobs/delete_value_job.rb +10 -0
  36. data/natural-backend/app/jobs/destroy_column_job.rb +10 -0
  37. data/natural-backend/app/jobs/destroy_database_job.rb +8 -0
  38. data/natural-backend/app/jobs/destroy_database_user_job.rb +8 -0
  39. data/natural-backend/app/jobs/destroy_table_job.rb +9 -0
  40. data/natural-backend/app/jobs/insert_value_job.rb +11 -0
  41. data/natural-backend/app/jobs/run_query_job.rb +35 -0
  42. data/natural-backend/app/jobs/sync_db_job.rb +80 -0
  43. data/natural-backend/app/jobs/update_column_type_job.rb +10 -0
  44. data/natural-backend/app/jobs/update_value_job.rb +10 -0
  45. data/natural-backend/app/mailers/application_mailer.rb +4 -0
  46. data/natural-backend/app/models/application_record.rb +3 -0
  47. data/natural-backend/app/models/column.rb +43 -0
  48. data/natural-backend/app/models/database.rb +37 -0
  49. data/natural-backend/app/models/project.rb +31 -0
  50. data/natural-backend/app/models/query.rb +20 -0
  51. data/natural-backend/app/models/row.rb +15 -0
  52. data/natural-backend/app/models/row_value.rb +30 -0
  53. data/natural-backend/app/models/table.rb +32 -0
  54. data/natural-backend/app/models/user.rb +10 -0
  55. data/natural-backend/app/serializers/column_serializer.rb +5 -0
  56. data/natural-backend/app/serializers/database_serializer.rb +6 -0
  57. data/natural-backend/app/serializers/project_serializer.rb +4 -0
  58. data/natural-backend/app/serializers/query_serializer.rb +3 -0
  59. data/natural-backend/app/serializers/row_serializer.rb +5 -0
  60. data/natural-backend/app/serializers/row_value_serializer.rb +5 -0
  61. data/natural-backend/app/serializers/table_serializer.rb +8 -0
  62. data/natural-backend/app/services/jwt_service.rb +17 -0
  63. data/natural-backend/app/views/layouts/mailer.html.erb +13 -0
  64. data/natural-backend/app/views/layouts/mailer.text.erb +1 -0
  65. data/natural-backend/bin/bundle +3 -0
  66. data/natural-backend/bin/rails +9 -0
  67. data/natural-backend/bin/rake +9 -0
  68. data/natural-backend/bin/run_migrations.sh +3 -0
  69. data/natural-backend/bin/setup +35 -0
  70. data/natural-backend/bin/spring +17 -0
  71. data/natural-backend/bin/update +29 -0
  72. data/natural-backend/config.ru +5 -0
  73. data/natural-backend/config/application.rb +33 -0
  74. data/natural-backend/config/boot.rb +3 -0
  75. data/natural-backend/config/cable.yml +10 -0
  76. data/natural-backend/config/database.yml +21 -0
  77. data/natural-backend/config/deploy.rb +36 -0
  78. data/natural-backend/config/deploy/production.rb +61 -0
  79. data/natural-backend/config/deploy/staging.rb +61 -0
  80. data/natural-backend/config/environment.rb +5 -0
  81. data/natural-backend/config/environments/development.rb +47 -0
  82. data/natural-backend/config/environments/production.rb +83 -0
  83. data/natural-backend/config/environments/test.rb +42 -0
  84. data/natural-backend/config/initializers/application_controller_renderer.rb +8 -0
  85. data/natural-backend/config/initializers/backtrace_silencers.rb +7 -0
  86. data/natural-backend/config/initializers/bugsnag.rb +3 -0
  87. data/natural-backend/config/initializers/cors.rb +16 -0
  88. data/natural-backend/config/initializers/filter_parameter_logging.rb +4 -0
  89. data/natural-backend/config/initializers/inflections.rb +16 -0
  90. data/natural-backend/config/initializers/json_api.rb +5 -0
  91. data/natural-backend/config/initializers/load_commands.rb +4 -0
  92. data/natural-backend/config/initializers/load_lib.rb +6 -0
  93. data/natural-backend/config/initializers/mime_types.rb +4 -0
  94. data/natural-backend/config/initializers/redis_classy.rb +1 -0
  95. data/natural-backend/config/initializers/sidekiq.rb +1 -0
  96. data/natural-backend/config/initializers/wrap_parameters.rb +14 -0
  97. data/natural-backend/config/locales/en.yml +33 -0
  98. data/natural-backend/config/puma.rb +56 -0
  99. data/natural-backend/config/routes.rb +14 -0
  100. data/natural-backend/config/schedule.rb +18 -0
  101. data/natural-backend/config/secrets.yml +32 -0
  102. data/natural-backend/config/spring.rb +6 -0
  103. data/natural-backend/db/migrate/20180408155000_create_projects.rb +9 -0
  104. data/natural-backend/db/migrate/20180408155011_create_databases.rb +10 -0
  105. data/natural-backend/db/migrate/20180409174859_create_tables.rb +9 -0
  106. data/natural-backend/db/migrate/20180409174916_create_columns.rb +11 -0
  107. data/natural-backend/db/migrate/20180409175800_create_rows.rb +9 -0
  108. data/natural-backend/db/migrate/20180409214650_create_row_values.rb +11 -0
  109. data/natural-backend/db/migrate/20180411110745_add_db_username_to_projects.rb +5 -0
  110. data/natural-backend/db/migrate/20180411145722_add_dbpw_to_projects.rb +5 -0
  111. data/natural-backend/db/migrate/20180411185924_add_database_identifier_to_databases.rb +6 -0
  112. data/natural-backend/db/migrate/20180412002908_add_dbid_to_rows.rb +5 -0
  113. data/natural-backend/db/migrate/20180412012433_create_queries.rb +11 -0
  114. data/natural-backend/db/migrate/20180429151758_create_users.rb +10 -0
  115. data/natural-backend/db/migrate/20180430094604_add_user_ref_to_projects.rb +5 -0
  116. data/natural-backend/db/migrate/20180430102945_add_user_ref_to_databases.rb +5 -0
  117. data/natural-backend/db/migrate/20180430102955_add_user_ref_to_tables.rb +5 -0
  118. data/natural-backend/db/migrate/20180430103004_add_user_ref_to_rows.rb +5 -0
  119. data/natural-backend/db/migrate/20180430103015_add_user_ref_to_columns.rb +5 -0
  120. data/natural-backend/db/migrate/20180430103024_add_user_ref_to_row_values.rb +5 -0
  121. data/natural-backend/db/migrate/20180430141537_add_api_token_projects.rb +5 -0
  122. data/natural-backend/db/schema.rb +112 -0
  123. data/natural-backend/db/seeds.rb +7 -0
  124. data/natural-backend/lib/database_manager/database_manager.rb +59 -0
  125. data/natural-backend/lib/database_manager/lib/connection.rb +49 -0
  126. data/natural-backend/lib/database_manager/lib/database.rb +65 -0
  127. data/natural-backend/lib/database_manager/lib/database_user.rb +46 -0
  128. data/natural-backend/lib/database_manager/lib/table.rb +129 -0
  129. data/natural-backend/public/assets/natural-frontend-598145a86019fc7faa2e0386ec6cb276.css +6 -0
  130. data/natural-backend/public/assets/natural-frontend-8e453ff9db7fc3a47e6d9e3de45aa19e.js +31 -0
  131. data/natural-backend/public/assets/vendor-7ffaee0528b64f886e9d1860fc719b5a.js +7359 -0
  132. data/natural-backend/public/assets/vendor-8bd8fa913b4f7f8b27f086c7bfd98b7f.css +1 -0
  133. data/natural-backend/public/index.html +26 -0
  134. data/natural-backend/public/robots.txt +3 -0
  135. data/natural-backend/roadmap.md +25 -0
  136. data/natural-backend/test/controllers/authentication_controller_test.rb +7 -0
  137. data/natural-backend/test/controllers/columns_controller_test.rb +38 -0
  138. data/natural-backend/test/controllers/databases_controller_test.rb +38 -0
  139. data/natural-backend/test/controllers/ember_controller_test.rb +7 -0
  140. data/natural-backend/test/controllers/projects_controller_test.rb +38 -0
  141. data/natural-backend/test/controllers/queries_controller_test.rb +38 -0
  142. data/natural-backend/test/controllers/row_values_controller_test.rb +38 -0
  143. data/natural-backend/test/controllers/rows_controller_test.rb +38 -0
  144. data/natural-backend/test/controllers/tables_controller_test.rb +38 -0
  145. data/natural-backend/test/fixtures/columns.yml +11 -0
  146. data/natural-backend/test/fixtures/databases.yml +9 -0
  147. data/natural-backend/test/fixtures/projects.yml +7 -0
  148. data/natural-backend/test/fixtures/queries.yml +9 -0
  149. data/natural-backend/test/fixtures/row_values.yml +11 -0
  150. data/natural-backend/test/fixtures/rows.yml +7 -0
  151. data/natural-backend/test/fixtures/tables.yml +7 -0
  152. data/natural-backend/test/fixtures/users.yml +9 -0
  153. data/natural-backend/test/jobs/add_column_job_test.rb +7 -0
  154. data/natural-backend/test/jobs/create_database_job_test.rb +7 -0
  155. data/natural-backend/test/jobs/create_database_user_job_test.rb +7 -0
  156. data/natural-backend/test/jobs/create_table_job_test.rb +7 -0
  157. data/natural-backend/test/jobs/delete_row_job_test.rb +7 -0
  158. data/natural-backend/test/jobs/delete_value_job_test.rb +7 -0
  159. data/natural-backend/test/jobs/destroy_database_job_test.rb +7 -0
  160. data/natural-backend/test/jobs/destroy_database_user_job_test.rb +7 -0
  161. data/natural-backend/test/jobs/destroy_table_job_test.rb +7 -0
  162. data/natural-backend/test/jobs/insert_value_job_test.rb +7 -0
  163. data/natural-backend/test/jobs/run_query_job_test.rb +7 -0
  164. data/natural-backend/test/jobs/sync_db_job_test.rb +7 -0
  165. data/natural-backend/test/jobs/update_value_job_test.rb +7 -0
  166. data/natural-backend/test/lib/database_manager/database_manager_test.rb +21 -0
  167. data/natural-backend/test/lib/database_manager/lib/database_test.rb +28 -0
  168. data/natural-backend/test/lib/database_manager/lib/database_user_test.rb +43 -0
  169. data/natural-backend/test/lib/database_manager/lib/table_test.rb +46 -0
  170. data/natural-backend/test/models/column_test.rb +7 -0
  171. data/natural-backend/test/models/database_test.rb +7 -0
  172. data/natural-backend/test/models/project_test.rb +7 -0
  173. data/natural-backend/test/models/query_test.rb +7 -0
  174. data/natural-backend/test/models/row_test.rb +7 -0
  175. data/natural-backend/test/models/row_value_test.rb +7 -0
  176. data/natural-backend/test/models/table_test.rb +7 -0
  177. data/natural-backend/test/models/user_test.rb +7 -0
  178. data/natural-backend/test/test_helper.rb +10 -0
  179. data/natural-frontend/LICENSE +21 -0
  180. data/natural-frontend/README.md +3 -0
  181. data/natural-frontend/app/adapters/application.js +33 -0
  182. data/natural-frontend/app/app.js +18 -0
  183. data/natural-frontend/app/components/column-editor.js +41 -0
  184. data/natural-frontend/app/components/row-editor.js +21 -0
  185. data/natural-frontend/app/components/row-value-editor.js +49 -0
  186. data/natural-frontend/app/controllers/application.js +11 -0
  187. data/natural-frontend/app/controllers/authenticate.js +16 -0
  188. data/natural-frontend/app/controllers/databases.js +22 -0
  189. data/natural-frontend/app/controllers/projects.js +18 -0
  190. data/natural-frontend/app/controllers/table.js +12 -0
  191. data/natural-frontend/app/controllers/table/rows.js +23 -0
  192. data/natural-frontend/app/controllers/tables.js +22 -0
  193. data/natural-frontend/app/helpers/plus-one.js +8 -0
  194. data/natural-frontend/app/index.html +25 -0
  195. data/natural-frontend/app/mixins/application-route-auth-mixin.js +8 -0
  196. data/natural-frontend/app/mixins/authenticated-route-mixin.js +10 -0
  197. data/natural-frontend/app/models/column.js +9 -0
  198. data/natural-frontend/app/models/database.js +9 -0
  199. data/natural-frontend/app/models/project.js +8 -0
  200. data/natural-frontend/app/models/row-value.js +8 -0
  201. data/natural-frontend/app/models/row.js +8 -0
  202. data/natural-frontend/app/models/table.js +9 -0
  203. data/natural-frontend/app/resolver.js +4 -0
  204. data/natural-frontend/app/router.js +22 -0
  205. data/natural-frontend/app/routes/application.js +5 -0
  206. data/natural-frontend/app/routes/authenticate.js +4 -0
  207. data/natural-frontend/app/routes/databases.js +15 -0
  208. data/natural-frontend/app/routes/function.js +20 -0
  209. data/natural-frontend/app/routes/functions.js +22 -0
  210. data/natural-frontend/app/routes/index.js +9 -0
  211. data/natural-frontend/app/routes/projects.js +8 -0
  212. data/natural-frontend/app/routes/table.js +17 -0
  213. data/natural-frontend/app/routes/table/rows.js +19 -0
  214. data/natural-frontend/app/routes/tables.js +16 -0
  215. data/natural-frontend/app/serializers/application.js +10 -0
  216. data/natural-frontend/app/services/authentication.js +38 -0
  217. data/natural-frontend/app/styles/app.scss +58 -0
  218. data/natural-frontend/app/templates/application.hbs +32 -0
  219. data/natural-frontend/app/templates/authenticate.hbs +7 -0
  220. data/natural-frontend/app/templates/components/api-usage-documentation.hbs +36 -0
  221. data/natural-frontend/app/templates/components/column-editor.hbs +37 -0
  222. data/natural-frontend/app/templates/components/row-editor.hbs +21 -0
  223. data/natural-frontend/app/templates/components/row-value-editor.hbs +1 -0
  224. data/natural-frontend/app/templates/databases.hbs +37 -0
  225. data/natural-frontend/app/templates/function.hbs +9 -0
  226. data/natural-frontend/app/templates/functions.hbs +30 -0
  227. data/natural-frontend/app/templates/index.hbs +15 -0
  228. data/natural-frontend/app/templates/projects.hbs +37 -0
  229. data/natural-frontend/app/templates/table.hbs +10 -0
  230. data/natural-frontend/app/templates/table/rows.hbs +23 -0
  231. data/natural-frontend/app/templates/tables.hbs +32 -0
  232. data/natural-frontend/config/environment.js +61 -0
  233. data/natural-frontend/config/targets.js +19 -0
  234. data/natural-frontend/deploy_rails_public.sh +6 -0
  235. data/natural-frontend/ember-cli-build.js +42 -0
  236. data/natural-frontend/package-lock.json +13288 -0
  237. data/natural-frontend/package.json +59 -0
  238. data/natural-frontend/public/robots.txt +3 -0
  239. data/natural-frontend/testem.js +20 -0
  240. data/natural-frontend/tests/index.html +33 -0
  241. data/natural-frontend/tests/integration/components/column-editor-test.js +27 -0
  242. data/natural-frontend/tests/integration/components/row-editor-test.js +27 -0
  243. data/natural-frontend/tests/integration/components/row-value-editor-test.js +27 -0
  244. data/natural-frontend/tests/integration/helpers/humanization-test.js +18 -0
  245. data/natural-frontend/tests/test-helper.js +9 -0
  246. data/natural-frontend/tests/unit/controllers/databases-test.js +13 -0
  247. data/natural-frontend/tests/unit/controllers/projects-test.js +13 -0
  248. data/natural-frontend/tests/unit/controllers/table-test.js +13 -0
  249. data/natural-frontend/tests/unit/controllers/table/rows-test.js +12 -0
  250. data/natural-frontend/tests/unit/controllers/tables-test.js +13 -0
  251. data/natural-frontend/tests/unit/models/column-test.js +15 -0
  252. data/natural-frontend/tests/unit/models/database-test.js +15 -0
  253. data/natural-frontend/tests/unit/models/project-test.js +15 -0
  254. data/natural-frontend/tests/unit/models/row-test.js +15 -0
  255. data/natural-frontend/tests/unit/models/rwo-value-test.js +15 -0
  256. data/natural-frontend/tests/unit/models/table-test.js +15 -0
  257. data/natural-frontend/tests/unit/routes/authenticate-test.js +11 -0
  258. data/natural-frontend/tests/unit/routes/databases-test.js +12 -0
  259. data/natural-frontend/tests/unit/routes/projects-test.js +12 -0
  260. data/natural-frontend/tests/unit/routes/table-test.js +12 -0
  261. data/natural-frontend/tests/unit/routes/table/rows-test.js +11 -0
  262. data/natural-frontend/tests/unit/routes/tables-test.js +12 -0
  263. metadata +303 -0
@@ -0,0 +1,5 @@
1
+ class AddUserRefToColumns < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_reference :columns, :user, foreign_key: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddUserRefToRowValues < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_reference :row_values, :user, foreign_key: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddApiTokenProjects < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :projects, :api_token, :string
4
+ end
5
+ end
@@ -0,0 +1,112 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(version: 20180430141537) do
14
+
15
+ # These are extensions that must be enabled in order to support this database
16
+ enable_extension "plpgsql"
17
+
18
+ create_table "columns", force: :cascade do |t|
19
+ t.string "name"
20
+ t.string "type"
21
+ t.bigint "table_id"
22
+ t.datetime "created_at", null: false
23
+ t.datetime "updated_at", null: false
24
+ t.bigint "user_id"
25
+ t.index ["table_id"], name: "index_columns_on_table_id"
26
+ t.index ["user_id"], name: "index_columns_on_user_id"
27
+ end
28
+
29
+ create_table "databases", force: :cascade do |t|
30
+ t.string "name"
31
+ t.bigint "project_id"
32
+ t.datetime "created_at", null: false
33
+ t.datetime "updated_at", null: false
34
+ t.string "database_identifier"
35
+ t.bigint "user_id"
36
+ t.index ["database_identifier"], name: "index_databases_on_database_identifier", unique: true
37
+ t.index ["project_id"], name: "index_databases_on_project_id"
38
+ t.index ["user_id"], name: "index_databases_on_user_id"
39
+ end
40
+
41
+ create_table "projects", force: :cascade do |t|
42
+ t.string "name"
43
+ t.datetime "created_at", null: false
44
+ t.datetime "updated_at", null: false
45
+ t.string "db_username"
46
+ t.string "db_password"
47
+ t.bigint "user_id"
48
+ t.string "api_token"
49
+ t.index ["user_id"], name: "index_projects_on_user_id"
50
+ end
51
+
52
+ create_table "queries", force: :cascade do |t|
53
+ t.text "request_data"
54
+ t.text "response_data"
55
+ t.bigint "database_id"
56
+ t.datetime "created_at", null: false
57
+ t.datetime "updated_at", null: false
58
+ t.index ["database_id"], name: "index_queries_on_database_id"
59
+ end
60
+
61
+ create_table "row_values", force: :cascade do |t|
62
+ t.bigint "row_id"
63
+ t.bigint "column_id"
64
+ t.text "value"
65
+ t.datetime "created_at", null: false
66
+ t.datetime "updated_at", null: false
67
+ t.bigint "user_id"
68
+ t.index ["column_id"], name: "index_row_values_on_column_id"
69
+ t.index ["row_id"], name: "index_row_values_on_row_id"
70
+ t.index ["user_id"], name: "index_row_values_on_user_id"
71
+ end
72
+
73
+ create_table "rows", force: :cascade do |t|
74
+ t.bigint "table_id"
75
+ t.datetime "created_at", null: false
76
+ t.datetime "updated_at", null: false
77
+ t.integer "db_id"
78
+ t.bigint "user_id"
79
+ t.index ["table_id"], name: "index_rows_on_table_id"
80
+ t.index ["user_id"], name: "index_rows_on_user_id"
81
+ end
82
+
83
+ create_table "tables", force: :cascade do |t|
84
+ t.string "name"
85
+ t.bigint "database_id"
86
+ t.datetime "created_at", null: false
87
+ t.datetime "updated_at", null: false
88
+ t.bigint "user_id"
89
+ t.index ["database_id"], name: "index_tables_on_database_id"
90
+ t.index ["user_id"], name: "index_tables_on_user_id"
91
+ end
92
+
93
+ create_table "users", force: :cascade do |t|
94
+ t.string "email"
95
+ t.string "password_digest"
96
+ t.datetime "created_at", null: false
97
+ t.datetime "updated_at", null: false
98
+ end
99
+
100
+ add_foreign_key "columns", "tables"
101
+ add_foreign_key "columns", "users"
102
+ add_foreign_key "databases", "projects"
103
+ add_foreign_key "databases", "users"
104
+ add_foreign_key "projects", "users"
105
+ add_foreign_key "row_values", "columns"
106
+ add_foreign_key "row_values", "rows"
107
+ add_foreign_key "row_values", "users"
108
+ add_foreign_key "rows", "tables"
109
+ add_foreign_key "rows", "users"
110
+ add_foreign_key "tables", "databases"
111
+ add_foreign_key "tables", "users"
112
+ end
@@ -0,0 +1,7 @@
1
+ # This file should contain all the record creation needed to seed the database with its default values.
2
+ # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
3
+ #
4
+ # Examples:
5
+ #
6
+ # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
7
+ # Character.create(name: 'Luke', movie: movies.first)
@@ -0,0 +1,59 @@
1
+ module Natural
2
+ class DatabaseManager
3
+ attr_reader :connection
4
+
5
+ def initialize
6
+ establish_default_connection
7
+ end
8
+
9
+ def connect_to_database(database_name)
10
+ @connection.close
11
+ @connection.database = ::Natural::Database.new(database_name)
12
+ @connection.establish_connection
13
+ @connection.database.connection = @connection
14
+ @connection
15
+ end
16
+
17
+ def establish_default_connection
18
+ @connection = ::Natural::Connection.new
19
+ @connection.load_rails_database_config
20
+ @connection.establish_connection
21
+ end
22
+
23
+ def database_user(username, password = nil)
24
+ database_user = ::Natural::DatabaseUser.new(username, password)
25
+ database_user.connection = connection
26
+ database_user
27
+ end
28
+
29
+ def create_user(username, password)
30
+ database_user(username, password).create
31
+ end
32
+
33
+ def destroy_user(username)
34
+ database_user(username).destroy
35
+ end
36
+
37
+ def user_exists?(username)
38
+ database_user(username).exists?
39
+ end
40
+
41
+ def database(identifier)
42
+ database = ::Natural::Database.new(identifier)
43
+ database.connection = connection
44
+ database
45
+ end
46
+
47
+ def create_database(identifier)
48
+ database(identifier).create
49
+ end
50
+
51
+ def destroy_database(identifier)
52
+ database(identifier).destroy
53
+ end
54
+
55
+ def database_exists?(identifier)
56
+ database(identifier).exists?
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,49 @@
1
+ module Natural
2
+ class Connection
3
+ attr_accessor :db_user
4
+ attr_accessor :database
5
+
6
+ def close
7
+ @connection.close
8
+ end
9
+
10
+ def establish_connection
11
+ options_hash = {
12
+ user: @db_user.username,
13
+ password: @db_user.password
14
+ }
15
+
16
+ if database.present?
17
+ options_hash.merge!({dbname: database.identifier})
18
+ end
19
+
20
+ @connection = PG.connect(options_hash)
21
+
22
+ end
23
+
24
+ def load_rails_database_config
25
+ config = Rails.configuration.database_configuration[Rails.env]
26
+
27
+ @db_user = ::Natural::DatabaseUser.new(config['username'],
28
+ config['password'])
29
+ end
30
+
31
+ def exec(*args, &block)
32
+ @connection.exec(*args, &block)
33
+ end
34
+
35
+ def clone_with_database(database)
36
+ clone = self.class.new
37
+ clone.db_user = self.db_user
38
+ clone.database = database
39
+ clone.establish_connection
40
+ clone
41
+ end
42
+ end
43
+
44
+ module ConnectionProvidable
45
+ def self.included(base)
46
+ attr_accessor :connection
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,65 @@
1
+ require_relative './connection.rb'
2
+
3
+ module Natural
4
+ class Database
5
+ include ::Natural::ConnectionProvidable
6
+
7
+ attr_reader :identifier
8
+
9
+ def initialize(identifier)
10
+ @identifier = identifier
11
+ end
12
+
13
+ def table(table_identifier)
14
+ table = Table.new(table_identifier)
15
+ table.connection = connection.clone_with_database(self)
16
+ table.database = self
17
+ table
18
+ end
19
+
20
+ def create_table(table_identifier)
21
+ table(table_identifier).create
22
+ end
23
+
24
+ def destroy_table(table_identifier)
25
+ table(table_identifier).destroy
26
+ end
27
+
28
+ def table_exists?(table_identifier)
29
+ table(table_identifier).exists?
30
+ end
31
+
32
+ def tables(associated_db_user)
33
+ connection.exec(
34
+ """
35
+ SELECT tablename FROM pg_catalog.pg_tables WHERE tableowner = \'#{associated_db_user}\';
36
+ """
37
+ )
38
+ end
39
+
40
+ def create
41
+ connection.exec(
42
+ """
43
+ CREATE DATABASE \"#{@identifier}\"
44
+ """
45
+ )
46
+ self
47
+ end
48
+
49
+ def destroy
50
+ connection.exec(
51
+ """
52
+ DROP DATABASE \"#{@identifier}\";
53
+ """
54
+ )
55
+ end
56
+
57
+ def exists?
58
+ '1' == connection.exec(
59
+ """
60
+ SELECT 1 FROM pg_database WHERE pg_database.datname = \'#{@identifier}\';
61
+ """
62
+ ).values[0].try(:[], 0)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,46 @@
1
+ require_relative './connection.rb'
2
+
3
+ module Natural
4
+ class DatabaseUser
5
+ include ::Natural::ConnectionProvidable
6
+ attr_reader :username, :password
7
+
8
+ def initialize(username, password = nil)
9
+ @username = username
10
+ @password = password
11
+ end
12
+
13
+ def create
14
+ connection.exec(
15
+ """
16
+ CREATE USER \"#{@username}\" WITH PASSWORD \'#{@password}\'
17
+ """
18
+ )
19
+ self
20
+ end
21
+
22
+ def destroy
23
+ connection.exec(
24
+ """
25
+ DROP USER \"#{@username}\";
26
+ """
27
+ )
28
+ end
29
+
30
+ def exists?
31
+ '1' == connection.exec(
32
+ """
33
+ SELECT 1 FROM pg_roles WHERE rolname='#{@username}'
34
+ """
35
+ ).values[0].try(:[], 0)
36
+ end
37
+
38
+ def grant(database)
39
+ connection.exec(
40
+ """
41
+ GRANT ALL PRIVILEGES ON DATABASE \"#{database.identifier}\" TO \"#{@username}\";
42
+ """
43
+ )
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,129 @@
1
+ require_relative './connection.rb'
2
+
3
+ module Natural
4
+ class Table
5
+ TYPE_IDENTIFIER_MAPPING = {
6
+ 'varchar_255' => 'varchar(255)',
7
+ }
8
+
9
+ include ::Natural::ConnectionProvidable
10
+
11
+ attr_reader :identifier
12
+ attr_accessor :database
13
+
14
+ def initialize(identifier)
15
+ @identifier = identifier
16
+ end
17
+
18
+ def create
19
+ connection.exec(
20
+ """
21
+ CREATE TABLE \"#{@identifier}\" (
22
+ id SERIAL
23
+ );
24
+ """
25
+ )
26
+ self
27
+ end
28
+
29
+ def destroy
30
+ connection.exec(
31
+ """
32
+ DROP TABLE \"#{@identifier}\";
33
+ """
34
+ )
35
+ end
36
+
37
+ def exists?
38
+ '1' == connection.exec(
39
+ """
40
+ SELECT 1
41
+ FROM pg_tables
42
+ WHERE tablename = '#{@identifier}'
43
+ """
44
+ ).values[0].try(:[], 0)
45
+ end
46
+
47
+ def add_column(name)
48
+ connection.exec(
49
+ """
50
+ ALTER TABLE \"#{@identifier}\"
51
+ ADD COLUMN \"#{name}\" varchar(255);
52
+ """
53
+ )
54
+ end
55
+
56
+ def update_column_type(name, type_identifier)
57
+ type = TYPE_IDENTIFIER_MAPPING[type_identifier] || type_identifier
58
+
59
+ connection.exec(
60
+ """
61
+ ALTER TABLE \"#{@identifier}\"
62
+ ALTER COLUMN \"#{name}\" TYPE #{type} USING (trim(\"#{name}\" )::#{type});
63
+ """
64
+ )
65
+ end
66
+
67
+ def destroy_column(name)
68
+ connection.exec(
69
+ """
70
+ ALTER TABLE \"#{@identifier}\"
71
+ DROP COLUMN \"#{name}\" RESTRICT;
72
+ """
73
+ )
74
+ end
75
+
76
+ def insert_value(column_name, value)
77
+ connection.exec(
78
+ """
79
+ INSERT INTO \"#{@identifier}\" (\"#{column_name}\")
80
+ VALUES ('#{single_quote_escape(value)}')
81
+ RETURNING ID;
82
+ """
83
+ ).values[0][0]
84
+ end
85
+
86
+ def update_value(column_name, id, value)
87
+ connection.exec(
88
+ """
89
+ UPDATE \"#{@identifier}\"
90
+ SET \"#{column_name}\" = \'#{single_quote_escape(value)}\'
91
+ WHERE id=#{id};
92
+ """
93
+ )
94
+ end
95
+
96
+ def single_quote_escape(string)
97
+ string.gsub("'", %q(''))
98
+ end
99
+
100
+ def delete_value(column_name, id)
101
+ connection.exec(
102
+ """
103
+ UPDATE \"#{@identifier}\"
104
+ SET \"#{column_name}\" = NULL
105
+ WHERE id=#{id};
106
+ """
107
+ )
108
+ end
109
+
110
+ def has_row?(id)
111
+ connection.exec(
112
+ """
113
+ SELECT 1
114
+ FROM \"#{@identifier}\"
115
+ WHERE id=#{id};
116
+ """
117
+ ).values[0][0] == '1'
118
+ end
119
+
120
+ def delete_row(id)
121
+ connection.exec(
122
+ """
123
+ DELETE FROM \"#{@identifier}\"
124
+ WHERE id=#{id};
125
+ """
126
+ )
127
+ end
128
+ end
129
+ end