rails_db 0.1 → 0.2

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/assets/javascripts/rails_db/application.js +7 -1
  4. data/app/controllers/rails_db/sql_controller.rb +24 -5
  5. data/app/helpers/rails_db/application_helper.rb +1 -1
  6. data/app/helpers/rails_db/flash_messages_helper.rb +44 -0
  7. data/app/views/layouts/rails_db/application.html.erb +1 -0
  8. data/app/views/rails_db/dashboard/index.html.erb +5 -2
  9. data/app/views/rails_db/shared/_footer.html.erb +7 -0
  10. data/app/views/rails_db/shared/_header.html.erb +7 -0
  11. data/app/views/rails_db/sql/_import_sample.html.erb +19 -0
  12. data/app/views/rails_db/sql/import.html.erb +37 -0
  13. data/config/routes.rb +3 -0
  14. data/lib/rails_db/adapters/base_adapter.rb +26 -0
  15. data/lib/rails_db/adapters/mysql.rb +15 -0
  16. data/lib/rails_db/adapters/postgres.rb +9 -0
  17. data/lib/rails_db/adapters/sqlite.rb +17 -0
  18. data/lib/rails_db/database.rb +24 -0
  19. data/lib/rails_db/rails_db_error.rb +5 -0
  20. data/lib/rails_db/result.rb +19 -0
  21. data/lib/rails_db/sql_import.rb +26 -0
  22. data/lib/rails_db/sql_query.rb +1 -1
  23. data/lib/rails_db/sql_query_data.rb +1 -1
  24. data/lib/rails_db/table_data.rb +2 -3
  25. data/lib/rails_db/version.rb +1 -1
  26. data/test/database_test.rb +11 -0
  27. data/test/dummy/app/views/home/index.html.erb +3 -1
  28. data/test/dummy/config/database.yml +4 -11
  29. data/test/dummy/db/development.sqlite3 +0 -0
  30. data/test/dummy/log/development.log +5732 -0
  31. data/test/dummy/log/test.log +513 -0
  32. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9Dv1AN2HoFMwjvSCCzmegkLXUJxe_iZ-0XOufRf-tFE.cache +1 -0
  33. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/F7wzDvE1vUNPUC4ZdkIfiwyHVkeOPL4pGwzzq-wuBO8.cache +0 -0
  34. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QuKueSfLQwv5cyuM_l_0EODvexy0h2PBp7EnBc4Vu-8.cache +1 -0
  35. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/VL6Fc1DN45EKm7QH9mclqvRrCbC1nu6inX4AlLYlBWE.cache +0 -0
  36. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WdVD_QcJoi6wyNWFFoAg-36LzsDzh1zBi5zamPh_vZk.cache +0 -0
  37. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_V6QCpwpPXKJNZEta0kCLvmOQwMNNTEIMOo1kYMK5oM.cache +0 -0
  38. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/enBbJ4kwxNcDB6tUtAT1Bw4I7Ib3WrVFHWBl-d-zm-4.cache +1 -0
  39. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/lcfsHC3R1udkB-YUXiVLMAoRPoMvtCbnfis33Dx9EJc.cache +1 -0
  40. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zJVqRZ01Vba8pBsFHjFbbagNHI468L0wWM3efZtgLIc.cache +1 -0
  41. data/test/sql_import_test.rb +14 -0
  42. data/test/sql_query_test.rb +14 -0
  43. data/test/table_test.rb +18 -0
  44. data/test/test_sql_mysql.sql +12 -0
  45. data/test/test_sql_postgres.sql +12 -0
  46. data/test/test_sql_sqlite.sql +5 -0
  47. metadata +59 -5
  48. data/lib/rails_db/sql_executor.rb +0 -20
  49. data/test/integration/navigation_test.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45bda56acd502bd41a558aa1ed3b372c767f4f3d
4
- data.tar.gz: 94e6098530d74c7018557c661a85fbcd5fa35855
3
+ metadata.gz: bbe9f9c6560e7360e74e2edbbe5f504ae13f1b31
4
+ data.tar.gz: f6af0d6abd5a343e1899dcb8eb329e3a1a12c874
5
5
  SHA512:
6
- metadata.gz: d5c4166f834cd28646a61677b7c8be727766b4359251806db4b5e3af181a80ae83fd433002d48be4ff5e45b9754e006e23df7368fd3294d159c44be634b8f35f
7
- data.tar.gz: 6af0ce12605da30d780d27172e90dac095dbbbc7b56ac42200025e5231affd66236dc8a42d3853e681bdf83b2d8e0afbafcf7e294b0c2ffe5bb5a79c36e23f6c
6
+ metadata.gz: 670c72a702fd40bbc38ee8971d98a6ed112b5cd50dcd5afa9272148783fa36c20366e72a2797a620adadac063fba400485610d09e276342a8e550606abd64862
7
+ data.tar.gz: f157de66f3b6acbc6e0a3d20845b2b72abae4a0c3744f9c10022890ddfcd958b68b990c731fe108a6a69ef789cbd66a099b241362484bd11982e3455603e865e
data/Rakefile CHANGED
@@ -29,7 +29,7 @@ require 'rake/testtask'
29
29
  Rake::TestTask.new(:test) do |t|
30
30
  t.libs << 'lib'
31
31
  t.libs << 'test'
32
- t.pattern = 'test/**/*_test.rb'
32
+ t.pattern = '**/*_test.rb'
33
33
  t.verbose = false
34
34
  end
35
35
 
@@ -8,6 +8,12 @@
8
8
  $(function(){
9
9
  $(document).foundation();
10
10
 
11
+ jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {
12
+ return function (elem) {
13
+ return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
14
+ };
15
+ });
16
+
11
17
  $('.per_page_pagination_select').on('change', function() {
12
18
  $(this).parents('form').submit();
13
19
  });
@@ -15,6 +21,6 @@ $(function(){
15
21
  $('#rails_db_tables_input').on('keyup', function() {
16
22
  value = $(this).val();
17
23
  $("#rails_db_tables a").show();
18
- $("#rails_db_tables a:not(:contains('" + value + "'))").hide();
24
+ $("#rails_db_tables a:not(:icontains('" + value + "'))").hide();
19
25
  });
20
26
  });
@@ -2,20 +2,39 @@ module RailsDb
2
2
  class SqlController < RailsDb::ApplicationController
3
3
 
4
4
  def index
5
- @sql = "#{params[:sql]}".strip
6
- @sql_query = RailsDb::SqlQuery.new(@sql).execute
5
+ load_query
7
6
  end
8
7
 
9
8
  def execute
10
- @sql = "#{params[:sql]}".strip
11
- @sql_query = RailsDb::SqlQuery.new(@sql).execute
9
+ load_query
12
10
  render :index
13
11
  end
14
12
 
15
13
  def csv
14
+ load_query
15
+ send_data(@sql_query.to_csv, :type => 'text/csv; charset=utf-8; header=present', :filename => "results.csv")
16
+ end
17
+
18
+ def import
19
+ end
20
+
21
+ def import_start
22
+ @importer = SqlImport.new(params[:file])
23
+ result = @importer.import
24
+ if result.ok?
25
+ flash[:notice] = 'File was successfully imported'
26
+ else
27
+ flash[:alert] = "Error occured during import: #{result.error.message}"
28
+ end
29
+ render :import
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def load_query
16
36
  @sql = "#{params[:sql]}".strip
17
37
  @sql_query = RailsDb::SqlQuery.new(@sql).execute
18
- send_data(@sql_query.to_csv, :type => 'text/csv; charset=utf-8; header=present', :filename => "results.csv")
19
38
  end
20
39
 
21
40
  end
@@ -3,7 +3,7 @@ module RailsDb
3
3
  include ::FontAwesome::Rails::IconHelper
4
4
 
5
5
  def rails_db_tables
6
- ActiveRecord::Base.connection.tables.sort - ['schema_migrations']
6
+ Database.tables
7
7
  end
8
8
 
9
9
  def title(str)
@@ -0,0 +1,44 @@
1
+ module RailsDb
2
+ module FlashMessagesHelper
3
+ # <div class="alert-box [success alert secondary]">
4
+ # This is an alert box.
5
+ # <a href="" class="close">&times;</a>
6
+ # </div>
7
+ DEFAULT_KEY_MATCHING = {
8
+ :alert => :alert,
9
+ :notice => :success,
10
+ :info => :info,
11
+ :secondary => :secondary,
12
+ :success => :success,
13
+ :error => :alert,
14
+ :warning => :warning
15
+ }
16
+ def display_flash_messages(key_matching = {})
17
+ key_matching = DEFAULT_KEY_MATCHING.merge(key_matching)
18
+ key_matching.default = :standard
19
+
20
+ result = capture do
21
+ flash.each do |key, value|
22
+ alert_class = key_matching[key.to_sym]
23
+ concat alert_box(value, alert_class)
24
+ end
25
+ end
26
+ flash.clear
27
+ result
28
+ end
29
+
30
+ private
31
+
32
+ def alert_box(value, alert_class)
33
+ content_tag :div, :data => { :alert => "" }, :class => "alert-box #{alert_class}" do
34
+ concat value
35
+ concat close_link
36
+ end
37
+ end
38
+
39
+ def close_link
40
+ link_to("&times;".html_safe, "#", :class => :close)
41
+ end
42
+
43
+ end
44
+ end
@@ -10,6 +10,7 @@
10
10
  </head>
11
11
 
12
12
  <body>
13
+ <%= display_flash_messages %>
13
14
  <%= render 'rails_db/shared/header' %>
14
15
  <div class="row">
15
16
  <div class="large-9 push-3 columns">
@@ -12,9 +12,12 @@
12
12
  <li>filter tables for easier navigation</li>
13
13
  <li>use history of you SQL queries</li>
14
14
  <li>see EXPLAIN results for your queries</li>
15
- <li>export data</li>
16
- <li>import data (future)</li>
15
+ <li>export data to CSV</li>
16
+ <li>import SQL files</li>
17
17
  <li>visualize SQL schema (future)</li>
18
+ <li>data-tables inside your app (future)</li>
19
+ <li>ajax-ify Rails DB (future)</li>
20
+ <li>CRUD for table records (future)</li>
18
21
  </ul>
19
22
 
20
23
  <br/>
@@ -26,6 +26,13 @@
26
26
  SQL Editor
27
27
  <% end %>
28
28
  </li>
29
+ <li>|</li>
30
+ <li>
31
+ <%= link_to rails_db.sql_import_path do %>
32
+ <%= fa_icon 'download' %>
33
+ Import
34
+ <% end %>
35
+ </li>
29
36
  </ul>
30
37
  </div>
31
38
  </div>
@@ -17,6 +17,13 @@
17
17
  SQL Editor
18
18
  <% end %>
19
19
  </li>
20
+ <li>|</li>
21
+ <li>
22
+ <%= link_to rails_db.sql_import_path do %>
23
+ <%= fa_icon 'download' %>
24
+ Import
25
+ <% end %>
26
+ </li>
20
27
  </ul>
21
28
  <ul class="inline-list right main_nav">
22
29
  <li>
@@ -0,0 +1,19 @@
1
+ <div id="sample_modal" class="reveal-modal" data-reveal aria-labelledby="modalTitle" aria-hidden="true" role="dialog">
2
+ <h2 id="modalTitle">Sample</h2>
3
+ <div class='scrollable sql_history_items'>
4
+ <pre>
5
+ update users set email = 'e1@e.com' where id = 5;
6
+ update users set email = 'e2@e.com' where id = 6;
7
+ update users set email = 'e3@e.com' where id = 7;
8
+
9
+ CREATE TABLE MyGuests (
10
+ id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
11
+ firstname VARCHAR(30) NOT NULL,
12
+ lastname VARCHAR(30) NOT NULL,
13
+ email VARCHAR(50),
14
+ reg_date TIMESTAMP
15
+ );
16
+ </pre>
17
+ </div>
18
+ <a class="close-reveal-modal" aria-label="Close">&#215;</a>
19
+ </div>
@@ -0,0 +1,37 @@
1
+ <% title "SQL Editor" %>
2
+
3
+ <%= form_tag :sql_start_import, multipart: true do %>
4
+ <h3>Import SQL File</h3>
5
+
6
+ <div class='row'>
7
+ <div class="large-11">
8
+ <label>
9
+ File
10
+ <%= file_field_tag :file %>
11
+ </label>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="row">
16
+ <div class="large-11">
17
+ <p><span class="radius secondary label">* <%= RailsDb::Adapters::BaseAdapter::MULTI_STATEMENT_HELP_TEXT %></span></p>
18
+ <%= submit_tag raw("&rarr; Import"), class: 'button small' %>
19
+ &nbsp;
20
+ &mdash;
21
+ &nbsp;
22
+ <a href="#" data-reveal-id="sample_modal" id='sample_modal_link'><%= fa_icon('bars') %> Sample</a></span>
23
+ <%= render 'import_sample' %>
24
+ </div>
25
+ </div>
26
+
27
+ <% if @importer && @importer.result.ok? %>
28
+ <div class='row'>
29
+ <div class="large-11">
30
+ <h4>Results</h4>
31
+ <p>
32
+ <span class="radius success label">File was successfully imported</span>
33
+ <span class="radius info label">Time: <%= @importer.time %> seconds</span>
34
+ </p>
35
+ <% end %>
36
+
37
+ <% end %>
@@ -7,6 +7,9 @@ RailsDb::Engine.routes.draw do
7
7
  get '/sql' => 'sql#index', as: :sql
8
8
  post '/execute' => 'sql#execute', as: :sql_execute
9
9
  post '/sql-csv' => 'sql#csv', as: :sql_csv
10
+
11
+ get '/import' => 'sql#import', as: :sql_import
12
+ post '/import-start' => 'sql#import_start', as: :sql_start_import
10
13
  end
11
14
 
12
15
  Rails.application.routes.draw do
@@ -0,0 +1,26 @@
1
+ module RailsDb
2
+ module Adapters
3
+
4
+ class BaseAdapter
5
+ extend ::RailsDb::Connection
6
+
7
+ MULTI_STATEMENT_HELP_TEXT = "EXPERIMENTAL: You can import only file with SQL statements separated by ';'. Each new statement must start from new line."
8
+
9
+ def self.execute(sql)
10
+ t0 = Time.now
11
+ connection.execute(sql)
12
+ Time.now - t0
13
+ end
14
+
15
+ def self.exec_query(sql, log = true)
16
+ t0 = Time.now
17
+ Rails.logger.debug "--> Executing: #{sql}" if log
18
+ results = connection.exec_query(sql)
19
+ execution_time = Time.now - t0
20
+ [results, execution_time]
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module RailsDb
2
+ module Adapters
3
+
4
+ class Mysql < BaseAdapter
5
+
6
+ def self.execute(sql)
7
+ sql.split(";\n").each do |statement|
8
+ connection.execute(statement)
9
+ end
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module RailsDb
2
+ module Adapters
3
+
4
+ class Postgres < BaseAdapter
5
+
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module RailsDb
2
+ module Adapters
3
+
4
+ class Sqlite < BaseAdapter
5
+
6
+ def self.execute(sql)
7
+ t0 = Time.now
8
+ sql.split(";\n").each do |statement|
9
+ connection.execute(statement)
10
+ end
11
+ Time.now - t0
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module RailsDb
2
+ class Database
3
+ include Connection
4
+ extend Connection
5
+
6
+ def self.tables
7
+ connection.tables.sort - ['schema_migrations']
8
+ end
9
+
10
+ def self.adapter
11
+ case connection.class.to_s
12
+ when /Mysql/
13
+ RailsDb::Adapters::Mysql
14
+ when /Postgre/
15
+ RailsDb::Adapters::Postgres
16
+ when /SQLite/
17
+ RailsDb::Adapters::Sqlite
18
+ else
19
+ RailsDb::Adapters::BaseAdapter
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module RailsDb
2
+ class RailsDbError < StandardError
3
+
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ module RailsDb
2
+ class Result
3
+
4
+ attr_reader :error
5
+
6
+ def initialize(error)
7
+ @error = error
8
+ end
9
+
10
+ def self.ok
11
+ Result.new(nil)
12
+ end
13
+
14
+ def ok?
15
+ error.nil?
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module RailsDb
2
+ class SqlImport
3
+ include Connection
4
+
5
+ attr_reader :time, :result
6
+
7
+ def initialize(file)
8
+ @file = file
9
+ end
10
+
11
+ def valid?
12
+ if @file.nil?
13
+ raise RailsDbError.new('Please select valid SQL file and continue')
14
+ end
15
+ end
16
+
17
+ def import
18
+ valid?
19
+ @time = Database.adapter.execute(@file.read)
20
+ @result = Result.ok
21
+ rescue RailsDbError, ActiveRecord::StatementInvalid => e
22
+ @result = Result.new(e)
23
+ end
24
+
25
+ end
26
+ end
@@ -17,7 +17,7 @@ module RailsDb
17
17
  end
18
18
 
19
19
  def load_data
20
- @data ||= SqlQueryData.new(self).load_data
20
+ @data ||= SqlQueryData.new(self).load_data
21
21
  end
22
22
 
23
23
  def execute
@@ -10,7 +10,7 @@ module RailsDb
10
10
  end
11
11
 
12
12
  def load_data
13
- result, @time = SqlExecutor.new(sql).execute
13
+ result, @time = Database.adapter.exec_query(sql)
14
14
  @columns = result.columns
15
15
  @rows = result.rows
16
16
  self
@@ -22,14 +22,13 @@ module RailsDb
22
22
  if per_page && offset
23
23
  commands.push("LIMIT #{per_page} OFFSET #{offset}")
24
24
  end
25
- executor = SqlExecutor.new(commands.join(' '))
26
- results, @time = executor.execute
25
+ results, @time = Database.adapter.exec_query(commands.join(' '))
27
26
  results
28
27
  end
29
28
  end
30
29
 
31
30
  def count
32
- connection.exec_query("SELECT COUNT(*) FROM #{table.name}").rows.flatten.last.to_i
31
+ Database.adapter.exec_query("SELECT COUNT(*) FROM #{table.name}")[0].rows.flatten.last.to_i
33
32
  end
34
33
 
35
34
  end