activerecord-comments 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e72374f3910386b8d9db461607ac65df0eb162f9
4
+ data.tar.gz: c662619926513774697a3b2cfad8d6546a14ac22
5
+ SHA512:
6
+ metadata.gz: d1f359c48d85d25e8bcd5823e619b221f71878ae95ec9a4bff7dc4b81d155dcf21a60cfbe6d48444ba3606c0a3214d55ef503501170ba8bfd2bbff1148fac3c2
7
+ data.tar.gz: d0d79995bc495bf4f8e28501ec04415f3dad0904ded665de73b7b1f6668177d9be531cb38b9fb4aed6f845120ea942050a14ec2ffbcd4db609d3e559e2a4e7e1
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activerecord-comments.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'pry'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Marton Somogyi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # ActiveRecord::Comments
2
+
3
+ Manage comments for SQL schemas. Set, get and remove comments on tables and columns. ActiveRecord bindings and executable with CLI.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'activerecord-comments'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install activerecord-comments
18
+
19
+ ## Executable usage
20
+
21
+ Set the DB environment variable to select from database configurations. Current value: "postgres"
22
+ -a, --action ACTION Action to perform: set, retrieve, remove
23
+ -t, --table TABLE Select table
24
+ -c, --column COLUMN Select column
25
+ -m, --comment COMMENT Comment to save
26
+ --conf DBCONF Database config YAML (default: /Users/<user>/activerecord_comments/config/database.yml)
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ require File.expand_path('../lib/active_record/comments/version', __FILE__)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'activerecord-comments'
6
+ spec.version = ActiveRecord::Comments::VERSION
7
+ spec.authors = ['Marton Somogyi']
8
+ spec.email = ['msomogyi@whitepages.com']
9
+ spec.summary = %q{Comments for SQL schemas}
10
+ spec.description = %q{Manage comments for SQL tables and columns}
11
+ spec.homepage = 'https://github.com/mcbuddha/activerecord-comments'
12
+ spec.license = 'MIT'
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.add_development_dependency 'bundler', '~> 1.6'
20
+ spec.add_development_dependency 'rake', '~> 10'
21
+ spec.add_development_dependency 'rspec', '~> 3'
22
+
23
+ spec.add_development_dependency 'pg', '~> 0.17'
24
+ spec.add_development_dependency 'mysql2', '~> 0'
25
+ spec.add_development_dependency 'sqlite3', '~> 0'
26
+
27
+ spec.add_runtime_dependency 'activerecord', '~> 3'
28
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pry'
3
+ require 'yaml'
4
+ require 'optparse'
5
+
6
+ require 'active_record/comments'
7
+
8
+ ENV['DB'] ||= 'postgres'
9
+
10
+ TYPES = %w(table column)
11
+ ACTIONS = %w(set retrieve remove)
12
+
13
+ options = {dbconf: File.expand_path('./config/database.yml', Dir.pwd)}
14
+ OptionParser.new do |opts|
15
+ opts.banner = <<USAGE
16
+ Set the DB environment variable to select from database configurations. Current value: "#{ENV['DB']}"
17
+ USAGE
18
+
19
+ opts.on('-a', '--action ACTION', ACTIONS, "Action to perform: #{ACTIONS.join(', ')}") { |action| options[:action] = action }
20
+ opts.on('-t', '--table TABLE', 'Select table') { |table| options[:table] = table }
21
+ opts.on('-c', '--column COLUMN', 'Select column') { |column| options[:column] = column }
22
+ opts.on('-m', '--comment COMMENT', 'Comment to save') { |comment| options[:comment] = comment }
23
+ opts.on('--conf DBCONF', "Database config YAML (default: #{options[:dbconf]})") { |dbconf| options[:dbconf] = dbconf }
24
+ end.parse!
25
+
26
+ abort 'You must specify a table' unless options[:table]
27
+ abort 'You must specify an action' unless options[:action]
28
+ abort 'You must specify a comment' if options[:action] == 'set' && options[:comment].nil?
29
+
30
+ DBCONF = YAML::load IO.read options[:dbconf] rescue abort "Error reading #{options[:dbconf]}: #{$!}"
31
+
32
+ ActiveRecord::Base.establish_connection(DBCONF[ENV['DB']]).connection rescue abort "Couldn't connect to #{options[:dbconf]}[#{ENV['DB']}]: #{$!}"
33
+
34
+ command = "#{options[:action]}_#{options[:column] ? 'column':'table'}_comment"
35
+ args = [options[:table].to_sym]
36
+ args << options[:column].to_sym if options[:column]
37
+ args << options[:comment] if options[:comment] and options[:action] != 'retrieve'
38
+
39
+ begin
40
+ result = ActiveRecord::Base.connection.send command, *args
41
+ puts result if options[:action] == 'retrieve'
42
+ rescue
43
+ abort "Error while executing query: #{$!}"
44
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_record'
2
+ require 'active_support/inflector'
3
+
4
+ require 'active_record/comments/version'
5
+
6
+ module ActiveRecord::Comments; end
7
+
8
+ require 'active_record/comments/connection_adapters/comment_definition'
9
+ require 'active_record/comments/connection_adapters/abstract_adapter'
10
+ require 'active_record/comments/connection_adapters/postgresql_adapter'
11
+ require 'active_record/comments/connection_adapters/abstract_sqlite_adapter'
12
+ require 'active_record/comments/connection_adapters/sqlite_adapter'
13
+ require 'active_record/comments/connection_adapters/sqlite3_adapter'
14
+ require 'active_record/comments/connection_adapters/mysql_adapter'
15
+ require 'active_record/comments/connection_adapters/mysql2_adapter'
16
+
17
+ module ActiveRecord::Comments
18
+ def self.setup
19
+ _cls = ->(l) { l.join('::').constantize }
20
+
21
+ ar_names = %w(ActiveRecord ConnectionAdapters AbstractAdapter)
22
+ ar_class = _cls.(ar_names)
23
+ arc_class = _cls.([self.name, *ar_names[1..-1]])
24
+ ar_class.send :include, arc_class unless ar_class.ancestors.include? arc_class
25
+
26
+ adapters = %w(PostgreSQL Mysql Mysql2)
27
+ adapters << (::ActiveRecord::VERSION::MAJOR <= 3 ? 'SQLite' : 'SQLite3')
28
+ adapters.each do |adapter|
29
+ begin require "active_record/connection_adapters/#{adapter.downcase}_adapter"
30
+ rescue LoadError => err; next; end
31
+
32
+ to_inject = "#{adapter}Adapter"
33
+ ar_class = _cls.([*ar_names[0..-2], to_inject])
34
+ arc_class = _cls.([self.name, *ar_names[1..-2], to_inject])
35
+ ar_class.module_eval do
36
+ ar_class.send :include, arc_class unless ar_class.ancestors.include?(arc_class)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ ActiveRecord::Comments.setup
@@ -0,0 +1,43 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module AbstractAdapter
3
+ def set_table_comment(table_name, comment_text)
4
+ end
5
+
6
+ def set_column_comment(table_name, column_name, comment_text)
7
+ end
8
+
9
+ def comments_supported?
10
+ false
11
+ end
12
+
13
+ # SQLite style - embedded comments
14
+ def inline_comments?
15
+ false
16
+ end
17
+
18
+ # PostgreSQL style - comment specific commands
19
+ def independent_comments?
20
+ false
21
+ end
22
+
23
+ def remove_table_comment(table_name)
24
+ set_table_comment(table_name, nil)
25
+ end
26
+
27
+ def remove_column_comment(table_name, column_name)
28
+ set_column_comment(table_name, column_name, nil)
29
+ end
30
+
31
+ def retrieve_table_comment(table_name)
32
+ nil
33
+ end
34
+
35
+ def retrieve_column_comments(table_name, *column_names)
36
+ {}
37
+ end
38
+
39
+ def retrieve_column_comment(table_name, column_name)
40
+ retrieve_column_comments(table_name, column_name)[column_name]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,70 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module AbstractSQLiteAdapter
3
+ def comments_supported?
4
+ true
5
+ end
6
+
7
+ def inline_comments?
8
+ true
9
+ end
10
+
11
+ def set_table_comment(table_name, comment_text)
12
+ alter_table(table_name, :comment => comment_text)
13
+ end
14
+
15
+ def set_column_comment(table_name, column_name, comment_text)
16
+ sql_type = primary_key(table_name) == column_name.to_s ?
17
+ :primary_key :
18
+ column_for(table_name, column_name).sql_type
19
+ change_column table_name, column_name, sql_type, :comment => comment_text
20
+ end
21
+
22
+ def retrieve_table_comment(table_name)
23
+ result = select_rows(lookup_comment_sql(table_name))
24
+ if result[0][0] =~ /CREATE (?:TEMPORARY )?TABLE #{quote_table_name table_name} [^\(]*\/\*(.*)\*\/ \(/
25
+ $1
26
+ end
27
+ end
28
+
29
+ def retrieve_column_comments(table_name, *column_names)
30
+ if column_names.empty?
31
+ return columns(table_name).inject({}) { |m, v| m[v.name.to_sym] = v.comment if v.comment.present?; m }
32
+ end
33
+ result = select_rows(lookup_comment_sql(table_name))
34
+ result[0][0] =~ /^CREATE (?:TEMPORARY )?TABLE "\w*" [^\(]*(?:\/\*.*\*\/ )?\((.*)\)[^\)]*$/
35
+ col_defs = $1
36
+ comment_matches = col_defs.scan(/"([^",]+)"[^,]*\/\*(.+?)\*\//)
37
+ comment_matches.inject({}){|m, row| m[row.first.to_sym] = row.last; m}
38
+ end
39
+
40
+ def column_for(table_name, column_name)
41
+ columns(table_name).detect{|col| col.name == column_name.to_s}
42
+ end
43
+
44
+ def comment_sql(comment_definition)
45
+ if comment_definition.nil? || comment_definition.comment_text.blank?
46
+ ""
47
+ else
48
+ " /*#{escaped_comment(comment_definition.comment_text)}*/"
49
+ end
50
+
51
+ end
52
+
53
+ def add_column_options!(sql, options)
54
+ super(sql, options)
55
+ if options.keys.include?(:comment)
56
+ sql << CommentDefinition.new(self, nil, nil, options[:comment]).to_sql
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def escaped_comment(comment)
63
+ comment.gsub(/\*\//, "*-/")
64
+ end
65
+
66
+ def lookup_comment_sql(table_name)
67
+ "select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = '#{table_name}'"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ class CommentDefinition < Struct.new(:adapter, :table, :column_name, :comment_text)
3
+ def to_dump
4
+ if table_comment?
5
+ "set_table_comment :#{table_name}, %{#{comment_text}}"
6
+ else
7
+ "set_column_comment :#{table_name}, :#{column_name}, %{#{comment_text}}"
8
+ end
9
+ end
10
+
11
+ def to_sql
12
+ adapter.comment_sql(self)
13
+ end
14
+ alias to_s :to_sql
15
+
16
+ def table_comment?
17
+ column_name.blank?
18
+ end
19
+
20
+ def table_name
21
+ table.respond_to?(:name) ? table.name : table
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module Mysql2Adapter
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include ActiveRecord::Comments::ConnectionAdapters::MysqlAdapter
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,79 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module MysqlAdapter
3
+ def comments_supported?
4
+ true
5
+ end
6
+
7
+ def set_table_comment(table_name, comment_text)
8
+ execute "ALTER TABLE #{quote_table_name table_name} COMMENT #{escaped_comment(comment_text)}"
9
+ end
10
+
11
+ def set_column_comment(table_name, column_name, comment_text)
12
+ pk_info = pk_and_sequence_for(table_name)
13
+ if pk_info && pk_info.first == column_name.to_s # change_column broken for :primary_key
14
+ primary_col_def = native_database_types[:primary_key].sub(/ PRIMARY KEY/i, '')
15
+ execute "ALTER TABLE #{quote_table_name table_name} CHANGE #{quote_column_name column_name} #{quote_column_name column_name} #{primary_col_def} COMMENT #{escaped_comment(comment_text)};"
16
+ else
17
+ column = column_for(table_name, column_name)
18
+ change_column table_name, column_name, column.sql_type, :comment => comment_text
19
+ end
20
+ end
21
+
22
+ def retrieve_table_comment(table_name)
23
+ result = select_rows(table_comment_sql(table_name))
24
+ result[0].nil? || result[0][0].blank? ? nil : result[0][0]
25
+ end
26
+
27
+ def retrieve_column_comments(table_name, *column_names)
28
+ result = select_rows(column_comment_sql(table_name, *column_names))
29
+ return {} if result.nil?
30
+ result.inject({}){|m, row| m[row[0].to_sym] = (row[1].blank? ? nil : row[1]); m}
31
+ end
32
+
33
+ def add_column_options!(sql, options)
34
+ super(sql, options)
35
+ if options.keys.include?(:comment)
36
+ sql << CommentDefinition.new(self, nil, nil, options[:comment]).to_sql
37
+ end
38
+ end
39
+
40
+ def comment_sql(comment_definition)
41
+ " COMMENT #{escaped_comment(comment_definition.comment_text)}"
42
+ end
43
+
44
+ def execute_comment(comment_definition)
45
+ if comment_definition.table_comment?
46
+ set_table_comment comment_definition.table_name, comment_definition.comment_text
47
+ else
48
+ set_column_comment comment_definition.table_name, comment_definition.column_name, comment_definition.comment_text
49
+ end
50
+ end
51
+
52
+ private
53
+ def escaped_comment(comment)
54
+ comment.nil? ? "''" : "'#{comment.gsub("'", "''").gsub("\\", "\\\\\\\\")}'"
55
+ end
56
+
57
+ def table_comment_sql(table_name)
58
+ <<SQL
59
+ SELECT table_comment FROM INFORMATION_SCHEMA.TABLES
60
+ WHERE table_schema = '#{database_name}'
61
+ AND table_name = '#{table_name}'
62
+ SQL
63
+ end
64
+
65
+ def column_comment_sql(table_name, *column_names)
66
+ col_matcher_sql = column_names.empty? ? "" : " AND column_name IN (#{column_names.map{|c_name| "'#{c_name}'"}.join(',')})"
67
+ <<SQL
68
+ SELECT column_name, column_comment FROM INFORMATION_SCHEMA.COLUMNS
69
+ WHERE table_schema = '#{database_name}'
70
+ AND table_name = '#{table_name}' #{col_matcher_sql}
71
+ SQL
72
+ end
73
+
74
+ def database_name
75
+ @database_name ||= select_rows("SELECT DATABASE()")[0][0]
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,77 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module PostgreSQLAdapter
3
+ def comments_supported?
4
+ true
5
+ end
6
+
7
+ def independent_comments?
8
+ true
9
+ end
10
+
11
+ def set_table_comment(table_name, comment_text)
12
+ execute CommentDefinition.new(self, table_name, nil, comment_text).to_sql
13
+ end
14
+
15
+ def set_column_comment(table_name, column_name, comment_text)
16
+ execute CommentDefinition.new(self, table_name, column_name, comment_text).to_sql
17
+ end
18
+
19
+ def retrieve_table_comment(table_name)
20
+ result = select_rows(table_comment_sql(table_name))
21
+ result[0].nil? ? nil : result[0][0]
22
+ end
23
+
24
+ def retrieve_column_comments(table_name, *column_names)
25
+ result = select_rows(column_comment_sql(table_name, *column_names))
26
+ return {} if result.nil?
27
+ return result.inject({}){|m, row| m[row[0].to_sym] = row[1]; m}
28
+ end
29
+
30
+ def comment_sql(comment_definition)
31
+ "COMMENT ON #{comment_target(comment_definition)} IS #{escaped_comment(comment_definition.comment_text)}"
32
+ end
33
+
34
+ private
35
+
36
+ def comment_target(comment_definition)
37
+ comment_definition.table_comment? ?
38
+ "TABLE #{quote_table_name(comment_definition.table_name)}" :
39
+ "COLUMN #{quote_table_name(comment_definition.table_name)}.#{quote_column_name(comment_definition.column_name)}"
40
+ end
41
+
42
+ def escaped_comment(comment)
43
+ comment.nil? ? 'NULL' : "'#{comment.gsub("'", "''")}'"
44
+ end
45
+
46
+ def table_comment_sql(table_name)
47
+ <<SQL
48
+ SELECT d.description FROM (
49
+ #{table_oids(table_name)}) tt
50
+ JOIN pg_catalog.pg_description d
51
+ ON tt.oid = d.objoid AND tt.tableoid = d.classoid AND d.objsubid = 0;
52
+ SQL
53
+ end
54
+
55
+ def column_comment_sql(table_name, *column_names)
56
+ col_matcher_sql = column_names.empty? ? "" : " a.attname IN (#{column_names.map{|c_name| "'#{c_name}'"}.join(',')}) AND "
57
+ <<SQL
58
+ SELECT a.attname, pg_catalog.col_description(a.attrelid, a.attnum)
59
+ FROM pg_catalog.pg_attribute a
60
+ JOIN (
61
+ #{table_oids(table_name)}) tt
62
+ ON tt.oid = a.attrelid
63
+ WHERE #{col_matcher_sql} a.attnum > 0 AND NOT a.attisdropped;
64
+ SQL
65
+ end
66
+
67
+ def table_oids(table_name)
68
+ <<SQL
69
+ SELECT c.oid, c.tableoid
70
+ FROM pg_catalog.pg_class c
71
+ WHERE c.relname = '#{table_name}'
72
+ AND c.relkind = 'r'
73
+ AND pg_catalog.pg_table_is_visible(c.oid)
74
+ SQL
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module SQLite3Adapter
3
+ include ActiveRecord::Comments::ConnectionAdapters::AbstractSQLiteAdapter
4
+
5
+ def create_table(table_name, options = {})
6
+ td = create_table_definition table_name, options[:temporary], options[:options]
7
+ td.base = self
8
+
9
+ unless options[:id] == false
10
+ pk = options.fetch(:primary_key) {
11
+ ActiveRecord::Base.get_primary_key table_name.to_s.singularize
12
+ }
13
+
14
+ td.primary_key pk, options.fetch(:id, :primary_key), options
15
+ end
16
+ td.comment options[:comment] if options.has_key?(:comment)
17
+
18
+ yield td if block_given?
19
+
20
+ if options[:force] && table_exists?(table_name)
21
+ drop_table(table_name, options)
22
+ end
23
+
24
+ execute schema_creation.accept td
25
+ td.indexes.each_pair { |c,o| add_index table_name, c, o }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ module ActiveRecord::Comments::ConnectionAdapters
2
+ module SQLiteAdapter
3
+ include ActiveRecord::Comments::ConnectionAdapters::AbstractSQLiteAdapter
4
+
5
+ def create_table(table_name, options = {})
6
+ td = ::ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
7
+ td.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
8
+ td.comment options[:comment] if options.has_key?(:comment)
9
+ td.base = self
10
+
11
+ yield td if block_given?
12
+
13
+ if options[:force] && table_exists?(table_name)
14
+ drop_table(table_name)
15
+ end
16
+
17
+ create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
18
+ create_sql << "#{quote_table_name(table_name)}#{td.table_comment} ("
19
+ create_sql << td.columns.map do |column|
20
+ column.to_sql + column.comment.to_s
21
+ end * ", "
22
+ create_sql << ") #{options[:options]}"
23
+ execute create_sql
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ module Comments
3
+ VERSION = '0.0.3'
4
+ end
5
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ TEST_COMMENTS =
4
+ [
5
+ %q{some "comment" with 'quotes'},
6
+ %q{other ; special \\ characters \' \"},
7
+ ]
8
+
9
+ describe ActiveRecord::Comments do
10
+ subject { ActiveRecord::Base.connection }
11
+ let(:table) { :test }
12
+ describe '#setup' do
13
+ context 'should define' do
14
+ it('set_table_comment') { expect(subject).to respond_to(:set_table_comment) }
15
+ it('retrieve_table_comment') { expect(subject).to respond_to(:retrieve_table_comment) }
16
+ it('remove_table_comment') { expect(subject).to respond_to(:remove_table_comment) }
17
+
18
+ it('set_column_comment') { expect(subject).to respond_to(:set_column_comment) }
19
+ it('retrieve_column_comment') { expect(subject).to respond_to(:retrieve_column_comment) }
20
+ it('retrieve_column_comments') { expect(subject).to respond_to(:retrieve_column_comments) }
21
+ it('remove_column_comment') { expect(subject).to respond_to(:remove_column_comment) }
22
+ end
23
+ end
24
+
25
+ describe 'table comments' do
26
+ let(:comment) { 'test comment' }
27
+ let(:comment2) { 'other test comment' }
28
+
29
+ before { subject.set_table_comment table, comment }
30
+
31
+ it 'should read same comment' do
32
+ expect(subject.retrieve_table_comment table).to eq(comment)
33
+ end
34
+
35
+ it 'should read last version' do
36
+ expect(subject.retrieve_table_comment table).to eq(comment)
37
+ subject.set_table_comment table, comment2
38
+ expect(subject.retrieve_table_comment table).to eq(comment2)
39
+ end
40
+
41
+ it 'should read nil after remove' do
42
+ subject.remove_table_comment table
43
+ expect(subject.retrieve_table_comment table).to be_nil
44
+ end
45
+ end
46
+
47
+ describe 'test_comments' do
48
+ TEST_COMMENTS.each do |comment|
49
+ it do
50
+ subject.set_table_comment table, comment
51
+ expect(subject.retrieve_table_comment table).to eq(comment)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'column comments' do
57
+ let(:comment) { 'some comment' }
58
+ let(:comment2) { 'some other comment' }
59
+ let(:comment3) { 'another comment' }
60
+
61
+ let(:col) { :field1 }
62
+ let(:col2) { :field2 }
63
+
64
+ context 'should read' do
65
+ it do
66
+ subject.set_column_comment table, col, comment
67
+ expect(subject.retrieve_column_comment table, col).to eq(comment)
68
+ end
69
+
70
+ it do
71
+ subject.set_column_comment table, col2, comment2
72
+ expect(subject.retrieve_column_comment table, col2).to eq(comment2)
73
+ end
74
+
75
+ it do
76
+ subject.set_column_comment table, col, comment
77
+ subject.set_column_comment table, col2, comment2
78
+ expect(subject.retrieve_column_comments table, col, col2).to eq(col => comment, col2 => comment2)
79
+ end
80
+
81
+ it do
82
+ subject.set_column_comment table, col, comment
83
+ expect(subject.retrieve_column_comment table, col).to eq(comment)
84
+ subject.remove_column_comment table, col
85
+ expect(subject.retrieve_column_comment table, col).to be_nil
86
+ end
87
+ end
88
+
89
+ describe 'test_comments' do
90
+ TEST_COMMENTS.each do |comment|
91
+ it do
92
+ subject.set_column_comment table, col, comment
93
+ expect(subject.retrieve_column_comment table, col).to eq(comment)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,18 @@
1
+ postgres:
2
+ adapter: postgresql
3
+ database: activerecord_comments_test
4
+ host: 127.0.0.1
5
+ username: postgres
6
+ password: postgres
7
+
8
+ mysql:
9
+ adapter: mysql2
10
+ database: activerecord_comments_test
11
+ user: root
12
+ password: password
13
+
14
+ sqlite:
15
+ adapter: sqlite3
16
+ database: test/db/activerecord_comments_test
17
+ pool: 5
18
+ timeout: 5000
@@ -0,0 +1,25 @@
1
+ $: << File.expand_path('../lib', __FILE__)
2
+
3
+ require 'yaml'
4
+ require 'pry'
5
+
6
+ require 'active_record/comments'
7
+
8
+ DBCONF = YAML::load(IO.read(File.expand_path('../config/database.yml', __FILE__)))
9
+ ENV['DB'] ||= 'postgres'
10
+ ActiveRecord::Base.establish_connection DBCONF[ENV['DB']]
11
+
12
+ RSpec.configure do |c|
13
+ c.around(:each) do |ex|
14
+ ActiveRecord::Migration.suppress_messages do
15
+ ActiveRecord::Schema.define do
16
+ create_table :test do |t|
17
+ t.string :field1
18
+ t.integer :field2
19
+ end
20
+ end
21
+ end
22
+ ex.run
23
+ ActiveRecord::Migration.suppress_messages { ActiveRecord::Schema.define { drop_table :test } }
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-comments
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Marton Somogyi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.17'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.17'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mysql2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3'
111
+ description: Manage comments for SQL tables and columns
112
+ email:
113
+ - msomogyi@whitepages.com
114
+ executables:
115
+ - activerecord-comments
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - activerecord-comments.gemspec
125
+ - bin/activerecord-comments
126
+ - lib/active_record/comments.rb
127
+ - lib/active_record/comments/connection_adapters/abstract_adapter.rb
128
+ - lib/active_record/comments/connection_adapters/abstract_sqlite_adapter.rb
129
+ - lib/active_record/comments/connection_adapters/comment_definition.rb
130
+ - lib/active_record/comments/connection_adapters/mysql2_adapter.rb
131
+ - lib/active_record/comments/connection_adapters/mysql_adapter.rb
132
+ - lib/active_record/comments/connection_adapters/postgresql_adapter.rb
133
+ - lib/active_record/comments/connection_adapters/sqlite3_adapter.rb
134
+ - lib/active_record/comments/connection_adapters/sqlite_adapter.rb
135
+ - lib/active_record/comments/version.rb
136
+ - spec/activerecord_comments_spec.rb
137
+ - spec/config/database.yml
138
+ - spec/spec_helper.rb
139
+ homepage: https://github.com/mcbuddha/activerecord-comments
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.2.2
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Comments for SQL schemas
163
+ test_files:
164
+ - spec/activerecord_comments_spec.rb
165
+ - spec/config/database.yml
166
+ - spec/spec_helper.rb