activerecord-comments 0.0.3

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.
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