browsql 0.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 (53) hide show
  1. data/.gitignore +35 -0
  2. data/.rvmrv +0 -0
  3. data/BrowSQL.gemspec +19 -0
  4. data/Gemfile +44 -0
  5. data/Gemfile.lock +122 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +34 -0
  8. data/Rakefile +5 -0
  9. data/app/assets/images/rails.png +0 -0
  10. data/app/assets/javascripts/brow_sql.js +15 -0
  11. data/app/assets/javascripts/brow_sql/tables.js.coffee +3 -0
  12. data/app/assets/stylesheets/brow_sql.css +13 -0
  13. data/app/assets/stylesheets/brow_sql/bootstrap_and_overrides.css.scss +29 -0
  14. data/app/assets/stylesheets/brow_sql/tables.css.scss +3 -0
  15. data/app/controllers/brow_sql/records_controller.rb +58 -0
  16. data/app/controllers/brow_sql/tables_controller.rb +53 -0
  17. data/app/controllers/brow_sql_controller.rb +2 -0
  18. data/app/helpers/application_helper.rb +2 -0
  19. data/app/helpers/tables_helper.rb +2 -0
  20. data/app/model/brow_sql/base.rb +11 -0
  21. data/app/model/brow_sql/record.rb +65 -0
  22. data/app/model/brow_sql/table.rb +78 -0
  23. data/app/views/brow_sql/records/_form.html.haml +10 -0
  24. data/app/views/brow_sql/records/edit.html.haml +4 -0
  25. data/app/views/brow_sql/records/index.html.haml +30 -0
  26. data/app/views/brow_sql/tables/_form.html.haml +14 -0
  27. data/app/views/brow_sql/tables/edit.html.haml +4 -0
  28. data/app/views/brow_sql/tables/index.html.haml +26 -0
  29. data/app/views/brow_sql/tables/show.html.haml +18 -0
  30. data/app/views/layouts/brow_sql.html.erb +76 -0
  31. data/config/locales/en.yml +5 -0
  32. data/config/routes.rb +7 -0
  33. data/db/seeds.rb +7 -0
  34. data/doc/README_FOR_APP +2 -0
  35. data/lib/BrowSQL.rb +10 -0
  36. data/lib/brow_sql/simple_form.rb +138 -0
  37. data/lib/brow_sql/version.rb +3 -0
  38. data/lib/tasks/.gitkeep +0 -0
  39. data/public/404.html +26 -0
  40. data/public/422.html +26 -0
  41. data/public/500.html +25 -0
  42. data/public/favicon.ico +0 -0
  43. data/public/index.html +241 -0
  44. data/public/robots.txt +5 -0
  45. data/test/fixtures/.gitkeep +0 -0
  46. data/test/functional/.gitkeep +0 -0
  47. data/test/functional/tables_controller_test.rb +7 -0
  48. data/test/integration/.gitkeep +0 -0
  49. data/test/performance/browsing_test.rb +12 -0
  50. data/test/test_helper.rb +13 -0
  51. data/test/unit/.gitkeep +0 -0
  52. data/test/unit/helpers/tables_helper_test.rb +4 -0
  53. metadata +106 -0
@@ -0,0 +1,2 @@
1
+ class BrowSqlController < ActionController::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module TablesHelper
2
+ end
@@ -0,0 +1,11 @@
1
+ class BrowSql::Base < ActiveRecord::Base
2
+ self.table_name = "sqlite_master"
3
+ # self.abstract_class = true
4
+
5
+ class Migrations < ActiveRecord::Migration
6
+ end
7
+
8
+ private
9
+
10
+
11
+ end
@@ -0,0 +1,65 @@
1
+ class BrowSql::Record
2
+ # include ActiveModel::Model
3
+ include ActiveModel::Validations
4
+ include ActiveModel::Conversion
5
+ extend ActiveModel::Naming
6
+ # {
7
+ # :string => { :name => "varchar", :limit => 255 },
8
+ # :text => { :name => "text" },
9
+ # :integer => { :name => "integer" },
10
+ # :float => { :name => "float" },
11
+ # :decimal => { :name => "decimal" },
12
+ # :datetime => { :name => "datetime" },
13
+ # :timestamp => { :name => "datetime" },
14
+ # :time => { :name => "time" },
15
+ # :date => { :name => "date" },
16
+ # :binary => { :name => "blob" },
17
+ # :boolean => { :name => "boolean" }
18
+ # }
19
+
20
+ class_attribute :connection, :instance_writer => false
21
+ self.connection = ActiveRecord::Base.connection
22
+
23
+ def initialize(params = nil, options = {})
24
+ params.each do |attr, value, type|
25
+ attributes.store(attr.to_s, type.type_cast(value))
26
+ end if params
27
+ end
28
+
29
+ def attributes
30
+ @attributes ||= {}
31
+ end
32
+
33
+ def persisted?
34
+ false
35
+ end
36
+
37
+ def destroy(table)
38
+ connection.execute('DELETE FROM "?" WHERE "?"."id"=?', table.name, table.name, id)
39
+ end
40
+
41
+ class << self
42
+ def all(table)
43
+ connection.execute("SELECT * FROM '#{table.name}'").map do |values|
44
+ self.new(values.each_with_index.map{|(k, v), i| [k, v, table.columns[i]] if table.columns[i] }.reject{|v| v.nil?})
45
+ end
46
+ end
47
+ end
48
+
49
+ def to_param
50
+ id
51
+ end
52
+
53
+ def method_missing(method, *args, &block)
54
+ if attributes.keys.include? method.to_s
55
+ attributes.fetch(method.to_s)
56
+ elsif attributes.keys.include? method.to_s.gsub("=", "")
57
+ attributes.store(method.to_s, *args)
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+
64
+ end
65
+
@@ -0,0 +1,78 @@
1
+ class BrowSql::Table < BrowSql::Base
2
+ # self.table_name = "sqlite_master"
3
+
4
+ self.store_full_sti_class = false
5
+ self.primary_key = :name
6
+
7
+ attr_accessible :name, :columns
8
+
9
+ validate :columns_must_be_unique
10
+
11
+ def columns_must_be_unique
12
+ column_changes.each do |column|
13
+ if columns.map(&:name).include? column.name
14
+ errors.add(:base, "Another column with the same name, already exists")
15
+ end
16
+ end
17
+ end
18
+
19
+ def self.sti_name #Override
20
+ "table"
21
+ end
22
+
23
+ def records
24
+ BrowSql::Record.all(self)
25
+ end
26
+
27
+ def find_record(id)
28
+ records.map do |record|
29
+ return record if record.id == id.to_i
30
+ end
31
+ return nil
32
+ end
33
+
34
+ def columns
35
+ klass.columns
36
+ end
37
+
38
+ def column_changes
39
+ @column_changes ||= []
40
+ @column_changes.map{|k,v| v }
41
+ end
42
+
43
+ def columns=(new_columns)
44
+ @column_changes = new_columns.reject{|k, v| v.current_name == v.name }
45
+ end
46
+
47
+ private
48
+
49
+ def self.find_sti_class(type_name) #Override
50
+ type_name = type_name.classify
51
+ super
52
+ end
53
+
54
+ def create #Override
55
+ end
56
+
57
+ def klass
58
+ name.classify.constantize
59
+ end
60
+
61
+ def update(attribute_names = @attributes.keys) #Override
62
+ # Migrations.rename_table self.name, @attributes["name"]
63
+ # attr_list = klass.columns.map { |c| c.name => c.type }
64
+ # raise column_changes.inspect
65
+ Migrations.change_table self.name do |t|
66
+ column_changes.each do |column|
67
+ if column.current_name
68
+ t.send(:rename, column.current_name.to_sym, column.name.to_sym)
69
+ else
70
+ t.send(column.type, column.name.to_sym)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+
77
+
78
+ end
@@ -0,0 +1,10 @@
1
+ = simple_form_for [@table, @record], wrapper: :horizontal, html: { :class => 'form-horizontal' } do |f|
2
+ - @table.columns.each do |column|
3
+ - puts "#{column.name}: #{column.type} #{column.to_yaml}"
4
+ = f.input column.name, as: column.type
5
+
6
+ .form-actions
7
+ = f.button :submit, :class => 'btn-primary'
8
+ = link_to t('.cancel', :default => t("helpers.links.cancel")),
9
+ table_records_path(@table), :class => 'btn'
10
+
@@ -0,0 +1,4 @@
1
+ .page-header
2
+ %h1= t '.title', :default => t('helpers.titles.edit', :model => "Record", :default => "Edit Record")
3
+
4
+ = render :partial => 'form'
@@ -0,0 +1,30 @@
1
+ .page-header
2
+ %h1= t '.title', :default => @table.name.titleize
3
+
4
+ %table.table.table-striped
5
+ %thead
6
+ %tr
7
+ - @table.columns.each do |column|
8
+ %th= column.name
9
+ %th Actions
10
+
11
+ %tbody
12
+ - @records.each do |record|
13
+ %tr
14
+ - @table.columns.each do |column|
15
+ %td= record.send(column.name)
16
+ %td
17
+ = link_to t('.edit', :default => t("helpers.links.edit")),
18
+ edit_table_record_path(@table, record), :class => 'btn btn-mini'
19
+ = link_to t('.destroy', :default => t("helpers.links.destroy")),
20
+ table_record_path(@table, record),
21
+ :method => :delete,
22
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
23
+ :class => 'btn btn-mini btn-danger'
24
+
25
+ .form-actions
26
+ = link_to t('.back', :default => t("helpers.links.back")),
27
+ tables_path, :class => 'btn'
28
+ = link_to t('.new', :default => t("helpers.links.new")),
29
+ new_table_record_path(@table),
30
+ :class => 'btn btn-primary'
@@ -0,0 +1,14 @@
1
+
2
+ = simple_form_for @table, wrapper: :horizontal, html: { :class => 'form-horizontal' } do |f|
3
+ = f.input :name, as: :string
4
+ - @table.columns.each_with_index do |column, i|
5
+ = f.simple_fields_for "columns][#{i}", column do |cf|
6
+ = cf.input :current_name, as: :hidden, :input_html => { :value => column.name }
7
+ = cf.input :name
8
+ = cf.input :type
9
+
10
+ .form-actions
11
+ = f.button :submit, :class => 'btn-primary'
12
+ = link_to t('.cancel', :default => t("helpers.links.cancel")),
13
+ tables_path, :class => 'btn'
14
+
@@ -0,0 +1,4 @@
1
+ .page-header
2
+ %h1= t '.title', :default => t('helpers.titles.edit', :model => "Table", :default => "Edit Table")
3
+
4
+ = render :partial => 'form'
@@ -0,0 +1,26 @@
1
+ .page-header
2
+ %h1= t '.title', :default => "Tables"
3
+
4
+ %table.table.table-striped
5
+ %thead
6
+ %tr
7
+ %th= t '.name', :default => "Name"
8
+ %th= t '.actions', :default => t("helpers.actions")
9
+
10
+ %tbody
11
+ - @tables.each do |table|
12
+ %tr
13
+ %td= link_to table.name, table_records_path(table)
14
+ %td
15
+ = link_to t('.edit', :default => t("helpers.links.edit")),
16
+ edit_table_path(table), :class => 'btn btn-mini'
17
+ = link_to t('.destroy', :default => t("helpers.links.destroy")),
18
+ table_path(table),
19
+ :method => :delete,
20
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
21
+ :class => 'btn btn-mini btn-danger'
22
+
23
+
24
+ = link_to t('.new', :default => t("helpers.links.new")),
25
+ new_table_path,
26
+ :class => 'btn btn-primary'
@@ -0,0 +1,18 @@
1
+ .page-header
2
+ %h1= @table.name
3
+
4
+ %dl.dl-horizontal
5
+ %dt
6
+ %strong Name
7
+ %dd= @table.name
8
+
9
+ .form-actions
10
+ = link_to t('.back', :default => t("helpers.links.back")),
11
+ tables_path, :class => 'btn'
12
+ = link_to t('.edit', :default => t("helpers.links.edit")),
13
+ edit_table_path(@table), :class => 'btn'
14
+ = link_to t('.destroy', :default => t("helpers.links.destroy")),
15
+ table_path(@table),
16
+ :method => 'delete',
17
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
18
+ :class => 'btn btn-danger'
@@ -0,0 +1,76 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title><%= content_for?(:title) ? yield(:title) : "BrowSQL" %></title>
8
+ <%= csrf_meta_tags %>
9
+
10
+ <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
11
+ <!--[if lt IE 9]>
12
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
13
+ <![endif]-->
14
+
15
+ <%= stylesheet_link_tag "brow_sql", :media => "all" %>
16
+
17
+ <!-- For third-generation iPad with high-resolution Retina display: -->
18
+ <!-- Size should be 144 x 144 pixels -->
19
+ <%= favicon_link_tag 'images/apple-touch-icon-144x144-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>
20
+
21
+ <!-- For iPhone with high-resolution Retina display: -->
22
+ <!-- Size should be 114 x 114 pixels -->
23
+ <%= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>
24
+
25
+ <!-- For first- and second-generation iPad: -->
26
+ <!-- Size should be 72 x 72 pixels -->
27
+ <%= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>
28
+
29
+ <!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
30
+ <!-- Size should be 57 x 57 pixels -->
31
+ <%= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>
32
+
33
+ <!-- For all other devices -->
34
+ <!-- Size should be 32 x 32 pixels -->
35
+ <%= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %>
36
+ </head>
37
+ <body>
38
+
39
+ <div class="navbar navbar-fluid-top">
40
+ <div class="navbar-inner">
41
+ <div class="container-fluid">
42
+ <a class="btn btn-navbar" data-target=".nav-collapse" data-toggle="collapse">
43
+ <span class="icon-bar"></span>
44
+ <span class="icon-bar"></span>
45
+ <span class="icon-bar"></span>
46
+ </a>
47
+ <%= link_to "BrowSQL", :root, class: "brand" %>
48
+ <div class="container-fluid nav-collapse">
49
+ <ul class="nav">
50
+ </ul>
51
+ </div><!--/.nav-collapse -->
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <div class="container-fluid">
57
+ <div class="row-fluid">
58
+ <div class="span12">
59
+ <%= bootstrap_flash %>
60
+ <%= yield %>
61
+ </div>
62
+ </div>
63
+
64
+ <footer>
65
+ <p>&copy; Company 2012</p>
66
+ </footer>
67
+
68
+ </div>
69
+
70
+ <!-- Javascripts
71
+ ================================================== -->
72
+ <!-- Placed at the end of the document so the pages load faster -->
73
+ <%= javascript_include_tag "brow_sql" %>
74
+
75
+ </body>
76
+ </html>
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ BrowSql::Engine.routes.draw do
2
+ root :to => 'tables#index'
3
+
4
+ resources :tables do
5
+ resources :records
6
+ end
7
+ end
data/db/seeds.rb ADDED
@@ -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 rake db:seed (or created alongside the db with db:setup).
3
+ #
4
+ # Examples:
5
+ #
6
+ # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
7
+ # Mayor.create(name: 'Emanuel', city: cities.first)
@@ -0,0 +1,2 @@
1
+ Use this README file to introduce your application and point to useful places in the API for learning more.
2
+ Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
data/lib/BrowSQL.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "brow_sql/version"
2
+ require "brow_sql/simple_form"
3
+
4
+ module BrowSql
5
+ class Engine < Rails::Engine
6
+ # engine_name "BrowSQL"
7
+ isolate_namespace BrowSql
8
+ end
9
+ # Your code goes here...
10
+ end
@@ -0,0 +1,138 @@
1
+ module BrowSql
2
+ # Use this setup block to configure all options available in SimpleForm.
3
+ SimpleForm.setup do |config|
4
+ # Wrappers are used by the form builder to generate a
5
+ # complete input. You can remove any component from the
6
+ # wrapper, change the order or even add your own to the
7
+ # stack. The options given below are used to wrap the
8
+ # whole input.
9
+
10
+ config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b|
11
+ b.use :html5
12
+ b.use :placeholder
13
+ b.use :label
14
+
15
+ b.wrapper :tag => 'div', :class => 'controls' do |ba|
16
+ ba.use :input
17
+ ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
18
+ ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' }
19
+ end
20
+ end
21
+
22
+ # The default wrapper to be used by the FormBuilder.
23
+ config.default_wrapper = :bootstrap
24
+
25
+ # Define the way to render check boxes / radio buttons with labels.
26
+ # Defaults to :nested for bootstrap config.
27
+ # :inline => input + label
28
+ # :nested => label > input
29
+ config.boolean_style = :nested
30
+
31
+ # Default class for buttons
32
+ config.button_class = 'btn'
33
+
34
+ # Method used to tidy up errors. Specify any Rails Array method.
35
+ # :first lists the first message for each field.
36
+ # Use :to_sentence to list all errors for each field.
37
+ # config.error_method = :first
38
+
39
+ # Default tag used for error notification helper.
40
+ config.error_notification_tag = :div
41
+
42
+ # CSS class to add for error notification helper.
43
+ config.error_notification_class = 'alert alert-error'
44
+
45
+ # ID to add for error notification helper.
46
+ # config.error_notification_id = nil
47
+
48
+ # Series of attempts to detect a default label method for collection.
49
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
50
+
51
+ # Series of attempts to detect a default value method for collection.
52
+ # config.collection_value_methods = [ :id, :to_s ]
53
+
54
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
55
+ # config.collection_wrapper_tag = nil
56
+
57
+ # You can define the class to use on all collection wrappers. Defaulting to none.
58
+ # config.collection_wrapper_class = nil
59
+
60
+ # You can wrap each item in a collection of radio/check boxes with a tag,
61
+ # defaulting to :span. Please note that when using :boolean_style = :nested,
62
+ # SimpleForm will force this option to be a label.
63
+ # config.item_wrapper_tag = :span
64
+
65
+ # You can define a class to use in all item wrappers. Defaulting to none.
66
+ # config.item_wrapper_class = nil
67
+
68
+ # How the label text should be generated altogether with the required text.
69
+ # config.label_text = lambda { |label, required| "#{required} #{label}" }
70
+
71
+ # You can define the class to use on all labels. Default is nil.
72
+ config.label_class = 'control-label'
73
+
74
+ # You can define the class to use on all forms. Default is simple_form.
75
+ # config.form_class = :simple_form
76
+
77
+ # You can define which elements should obtain additional classes
78
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
79
+
80
+ # Whether attributes are required by default (or not). Default is true.
81
+ # config.required_by_default = true
82
+
83
+ # Tell browsers whether to use default HTML5 validations (novalidate option).
84
+ # Default is enabled.
85
+ config.browser_validations = false
86
+
87
+ # Collection of methods to detect if a file type was given.
88
+ # config.file_methods = [ :mounted_as, :file?, :public_filename ]
89
+
90
+ # Custom mappings for input types. This should be a hash containing a regexp
91
+ # to match as key, and the input type that will be used when the field name
92
+ # matches the regexp as value.
93
+ # config.input_mappings = { /count/ => :integer }
94
+
95
+ # Custom wrappers for input types. This should be a hash containing an input
96
+ # type as key and the wrapper that will be used for all inputs with specified type.
97
+ # config.wrapper_mappings = { :string => :prepend }
98
+
99
+ # Default priority for time_zone inputs.
100
+ # config.time_zone_priority = nil
101
+
102
+ # Default priority for country inputs.
103
+ # config.country_priority = nil
104
+
105
+ # Default size for text inputs.
106
+ # config.default_input_size = 50
107
+
108
+ # When false, do not use translations for labels.
109
+ # config.translate_labels = true
110
+
111
+ # Automatically discover new inputs in Rails' autoload path.
112
+ # config.inputs_discovery = true
113
+
114
+ # Cache SimpleForm inputs discovery
115
+ # config.cache_discovery = !Rails.env.development?
116
+ end
117
+
118
+ module SimpleForm
119
+ module Components
120
+ module Placeholders
121
+
122
+ def placeholder_text
123
+ placeholder = options[:placeholder]
124
+ if placeholder.is_a?(String)
125
+ placeholder
126
+ elsif SimpleForm.translate_labels && (translated_placeholder = translate(:placeholders))
127
+ translated_placeholder
128
+ elsif object.class.respond_to?(:human_attribute_name)
129
+ object.class.human_attribute_name(reflection_or_attribute_name.to_s)
130
+ else
131
+ attribute_name.to_s.humanize
132
+ end
133
+ end
134
+
135
+ end
136
+ end
137
+ end
138
+ end