pg_comment 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pg_comment.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) 2011 Arthur Shagall
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = PgComment
2
+
3
+ In any PostgreSQL database where the Rails app is not the only consumer, it is very helpful to have comments on the various database entities. PgComment adds methods to migrations to set and remove comments on columns and tables.
4
+
5
+ Obviously, only the PostgreSQL adapter is supported.
6
+
7
+ == Warning
8
+
9
+ This is still experimental. If it blows up your Rails app, I will gladly welcome your bug reports.
10
+
11
+ This has only been tested on Ruby 1.9.2 and JRuby 1.6.4.
12
+
13
+ == Installation
14
+
15
+ TODO: finish up once I publish and fix any initial bugs.
16
+
17
+ == Usage
18
+
19
+ PgComment adds four methods to migrations:
20
+
21
+ * set_table_comment(table_name, comment)
22
+ * remove_table_comment(table_name)
23
+ * set_column_comment(table_name, column_name, comment)
24
+ * remove_column_comment(table_name, column_name, comment)
25
+
26
+ Set a comment on the given table.
27
+
28
+ set_table_comment :phone_numbers, 'This table stores phone numbers that conform to the North American Numbering Plan.'
29
+
30
+ Sets a comment on a given column of a given table.
31
+
32
+ set_column_comment :phone_numbers, :npa, 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.'
33
+
34
+ Removes any comment from the given table.
35
+
36
+ remove_table_comment :phone_numbers
37
+
38
+ Removes any comment from the given column of a given table.
39
+
40
+ remove_column_comment :phone_numbers, :npa
41
+
42
+ PgComment also adds extra methods to change_table.
43
+
44
+ Set comments:
45
+
46
+ change_table :phone_numbers do |t|
47
+ t.set_table_comment 'This table stores phone numbers that conform to the North American Numbering Plan.'
48
+ t.set_column_comment :npa, 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.'
49
+ end
50
+
51
+ Remove comments:
52
+
53
+ change_table :phone_numbers do |t|
54
+ t.remove_table_comment
55
+ t.remove_column_comment :npa
56
+ end
57
+
58
+ == License
59
+
60
+ Copyright (c) 2011 Arthur Shagall
61
+
62
+ Released under the MIT License. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/*test.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,51 @@
1
+ module PgComment
2
+ module ConnectionAdapters
3
+ module SchemaDefinitions
4
+ def self.included(base)
5
+ base::Table.class_eval do
6
+ include PgComment::ConnectionAdapters::Table
7
+ end
8
+ end
9
+ end
10
+
11
+ module Table
12
+ extend ActiveSupport::Concern
13
+
14
+ # Sets the comment on the table
15
+ #
16
+ # ===== Example
17
+ # ====== Set comment on table
18
+ # t.set_table_comment 'This table stores phone numbers that conform to the North American Numbering Plan.'
19
+ def set_table_comment(comment)
20
+ @base.set_table_comment(@table_name, comment)
21
+ end
22
+
23
+ # Removes any comment from the table
24
+ #
25
+ # ===== Example
26
+ # ====== Remove table comment
27
+ # t.remove_table_comment
28
+ def remove_table_comment
29
+ @base.remove_table_comment(@table_name)
30
+ end
31
+
32
+ # Sets the comment for a given column
33
+ #
34
+ # ===== Example
35
+ # ====== Set comment on the npa column
36
+ # t.set_column_comment :npa, 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.'
37
+ def set_column_comment(column_name, comment)
38
+ @base.set_column_comment(@table_name, column_name, comment)
39
+ end
40
+
41
+ # Removes any comment for a given column
42
+ #
43
+ # ===== Example
44
+ # ====== Remove comment from the npa column
45
+ # t.remove_column_comment :npa
46
+ def remove_column_comment(column_name)
47
+ @base.remove_column_comment(@table_name, column_name)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ module PgComment
2
+ module ConnectionAdapters
3
+ module SchemaStatements
4
+ def self.included(base)
5
+ base::AbstractAdapter.class_eval do
6
+ include PgComment::ConnectionAdapters::AbstractAdapter
7
+ end
8
+ end
9
+ end
10
+
11
+ module AbstractAdapter
12
+
13
+ def supports_comments?
14
+ false
15
+ end
16
+
17
+ # Sets a comment on the given table.
18
+ #
19
+ # ===== Example
20
+ # ====== Creating a comment on phone_numbers table
21
+ # set_table_comment :phone_numbers, 'This table stores phone numbers that conform to the North American Numbering Plan.'
22
+ def set_table_comment(table_name, comment)
23
+ # Does nothing
24
+ end
25
+
26
+ # Sets a comment on a given column of a given table.
27
+ #
28
+ # ===== Example
29
+ # ====== Creating a comment on npa column of table phone_numbers
30
+ # set_column_comment :phone_numbers, :npa, 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.'
31
+ def set_column_comment(table_name, column_name, comment)
32
+ # Does nothing
33
+ end
34
+
35
+ # Removes any comment from the given table.
36
+ #
37
+ # ===== Example
38
+ # ====== Removing comment from phone numbers table
39
+ # remove_table_comment :phone_numbers
40
+ def remove_table_comment(table_name)
41
+
42
+ end
43
+
44
+ # Removes any comment from the given column of a given table.
45
+ #
46
+ # ===== Example
47
+ # ====== Removing comment from the npa column of table phone_numbers
48
+ # remove_column_comment :phone_numbers, :npa
49
+ def remove_column_comment(table_name, column_name)
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ module PgComment
2
+ module ConnectionAdapters
3
+ module PostgreSQLAdapter
4
+ def supports_comments?
5
+ true
6
+ end
7
+
8
+ def set_table_comment(table_name, comment)
9
+ sql = "COMMENT ON TABLE #{quote_table_name(table_name)} IS $$#{comment}$$;"
10
+ execute sql
11
+ end
12
+
13
+ def set_column_comment(table_name, column_name, comment)
14
+ sql = "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS $$#{comment}$$;"
15
+ execute sql
16
+ end
17
+
18
+ def remove_table_comment(table_name)
19
+ sql = "COMMENT ON TABLE #{quote_table_name(table_name)} IS NULL;"
20
+ execute sql
21
+ end
22
+
23
+ def remove_column_comment(table_name, column_name)
24
+ sql = "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS NULL;"
25
+ execute sql
26
+ end
27
+ =begin
28
+ --Fetch all comments
29
+ SELECT c.relname as table_name, a.attname as column_name, d.description as comment
30
+ FROM pg_description d
31
+ JOIN pg_class c ON c.oid = d.objoid
32
+ LEFT OUTER JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = d.objsubid
33
+ WHERE c.relkind = 'r'
34
+ ORDER BY c.relname
35
+ =end
36
+ def comments(table_name)
37
+ com = select_all %{
38
+ SELECT a.attname AS column_name, d.description AS comment
39
+ FROM pg_description d
40
+ JOIN pg_class c on c.oid = d.objoid
41
+ LEFT OUTER JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = d.objsubid
42
+ WHERE c.relkind = 'r' AND c.relname = '#{table_name}'
43
+ }
44
+ com.map do |row|
45
+ [ row['column_name'], row['comment'] ]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ [:PostgreSQLAdapter, :JdbcAdapter].each do |adapter|
53
+ begin
54
+ ActiveRecord::ConnectionAdapters.const_get(adapter).class_eval do
55
+ include PgComment::ConnectionAdapters::PostgreSQLAdapter
56
+ end
57
+ rescue
58
+ end
59
+ end
@@ -0,0 +1,32 @@
1
+ module PgComment
2
+ module Migration
3
+ module CommandRecorder
4
+ def set_table_comment(*args)
5
+ record(:set_table_comment, args)
6
+ end
7
+
8
+ def remove_table_comment(*args)
9
+ record(:remove_table_comments, args)
10
+ end
11
+
12
+ def set_column_comment(*args)
13
+ record(:set_column_comment, args)
14
+ end
15
+
16
+ def remove_column_comment(*args)
17
+ record(:remove_column_comment, args)
18
+ end
19
+
20
+ def invert_set_table_comment(args)
21
+ table_name = args.first
22
+ [:remove_table_comment, [table_name]]
23
+ end
24
+
25
+ def invert_set_column_comment(args)
26
+ table_name = args[0]
27
+ column_name = args[1]
28
+ [:remove_column_comment, [table_name, column_name]]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ module PgComment
2
+ class Railtie < Rails::Railtie
3
+ initializer 'pg_comment.load_adapter' do
4
+ ActiveSupport.on_load :active_record do
5
+ ActiveRecord::ConnectionAdapters.module_eval do
6
+ include PgComment::ConnectionAdapters::SchemaStatements
7
+ include PgComment::ConnectionAdapters::SchemaDefinitions
8
+ end
9
+
10
+ ActiveRecord::SchemaDumper.class_eval do
11
+ include PgComment::SchemaDumper
12
+ end
13
+
14
+ if defined?(ActiveRecord::Migration::CommandRecorder)
15
+ ActiveRecord::Migration::CommandRecorder.class_eval do
16
+ include PgComment::Migration::CommandRecorder
17
+ end
18
+ end
19
+
20
+ conf_name = ActiveRecord::Base.connection_pool.spec.config[:adapter]
21
+ if conf_name == 'postgresql' then
22
+ require 'pg_comment/connection_adapters/postgresql_adapter'
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ module PgComment
2
+ module SchemaDumper
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ alias_method_chain :tables, :comments
7
+ end
8
+
9
+ def tables_with_comments(stream)
10
+ tables_without_comments(stream)
11
+ @connection.tables.sort.each do |table_name|
12
+ dump_comments(table_name, stream)
13
+ end
14
+ end
15
+
16
+ def dump_comments(table_name, stream)
17
+ unless (comments = @connection.comments(table_name)).empty?
18
+ comment_statements = comments.map do |row|
19
+ column_name = row[0]
20
+ comment = row[1]
21
+
22
+ if column_name
23
+ " set_column_comment '#{table_name}', '#{column_name}', '#{comment.gsub(/'/, "\\\\'")}'"
24
+ else
25
+ " set_table_comment '#{table_name}', '#{comment}'"
26
+ end
27
+
28
+ end
29
+
30
+ stream.puts comment_statements.join("\n")
31
+ stream.puts
32
+ end
33
+ end
34
+ private :dump_comments
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module PgComment
2
+ VERSION = "0.0.3"
3
+ end
data/lib/pg_comment.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "pg_comment/version"
2
+ require 'active_support/all'
3
+
4
+ module PgComment
5
+ extend ActiveSupport::Autoload
6
+ autoload :Adapter
7
+ autoload :SchemaDumper
8
+
9
+ module ConnectionAdapters
10
+ extend ActiveSupport::Autoload
11
+
12
+ autoload_under 'abstract' do
13
+ autoload :SchemaDefinitions
14
+ autoload :SchemaStatements
15
+ end
16
+ end
17
+
18
+ module Migration
19
+ autoload :CommandRecorder, 'pg_comment/migration/command_recorder'
20
+ end
21
+ end
22
+
23
+ require 'pg_comment/railtie' if defined?(Rails)
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pg_comment/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "pg_comment"
7
+ s.version = PgComment::VERSION
8
+ s.authors = ["Arthur Shagall"]
9
+ s.email = ["arthur.shagall@gmail.com"]
10
+ s.homepage = "https://github.com/albertosaurus/pg_comment"
11
+ s.summary = 'Postgres Comments for Rails'
12
+ s.description = 'Adds helper methods to migrations and pulls out comments into schema.rb'
13
+
14
+ s.rubyforge_project = "pg_comment"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('activerecord', '>= 3.0.0')
22
+ s.add_development_dependency("test-unit")
23
+ end
@@ -0,0 +1,9 @@
1
+ class FakeConnection
2
+ def initialize(args = {})
3
+ @comments = args[:comments]
4
+ end
5
+
6
+ def comments(table_name)
7
+ @comments
8
+ end
9
+ end
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ gem 'test-unit'
3
+ require 'test/unit'
4
+ require 'pg_comment/connection_adapters/postgresql_adapter'
5
+
6
+ class PostgreSQLAdapterTest < Test::Unit::TestCase
7
+ class Adapter
8
+ attr_reader :buffer
9
+ def select_results=(val)
10
+ @select_results = val
11
+ end
12
+
13
+ def select_all(*args)
14
+ @select_results
15
+ end
16
+
17
+ def quote_table_name(table_name)
18
+ table_name
19
+ end
20
+
21
+ def quote_column_name(column_name)
22
+ column_name
23
+ end
24
+
25
+ def execute(sql)
26
+ @buffer ||= []
27
+ @buffer << sql
28
+ end
29
+
30
+ include PgComment::ConnectionAdapters::PostgreSQLAdapter
31
+ end
32
+
33
+ def test_sql_generation
34
+ expected = [ "COMMENT ON TABLE my_table IS $$table comment$$;",
35
+ "COMMENT ON COLUMN my_table.my_column IS $$column comment$$;",
36
+ "COMMENT ON TABLE my_table IS NULL;",
37
+ "COMMENT ON COLUMN my_table.my_column IS NULL;" ]
38
+
39
+ a = Adapter.new
40
+ a.set_table_comment :my_table, 'table comment'
41
+ a.set_column_comment :my_table, :my_column, 'column comment'
42
+ a.remove_table_comment :my_table
43
+ a.remove_column_comment :my_table, :my_column
44
+ assert_equal expected, a.buffer
45
+ end
46
+
47
+ def test_comments
48
+ a = Adapter.new
49
+ expected = [ { 'column_name' => nil, 'comment' => 'table comment' },
50
+ { 'column_name' => 'column1', 'comment' => 'column comment 1' },
51
+ { 'column_name' => 'column2', 'comment' => 'column comment 2' } ]
52
+ a.select_results = expected
53
+ results = a.comments( nil )
54
+ assert_not_nil results
55
+ assert_equal 3, results.size, "Should have three comment rows."
56
+ results.each_with_index do |comment_row, index|
57
+ column_name = comment_row[0]
58
+ comment = comment_row[1]
59
+ assert_equal expected[index]['column_name'], column_name
60
+ assert_equal expected[index]['comment'], comment
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,47 @@
1
+ require 'fake_connection'
2
+ require 'rubygems'
3
+ gem 'test-unit'
4
+ require 'test/unit'
5
+ require 'active_record'
6
+ require 'pg_comment/schema_dumper'
7
+
8
+ class SchemaDumperTest < Test::Unit::TestCase
9
+ class SchemaDumpContainer
10
+ def initialize
11
+ @connection = FakeConnection.new( :comments => [[nil, 'table comment'],
12
+ ['c1', 'column1 comment'],
13
+ ['c2', 'column2 comment']] )
14
+ end
15
+
16
+ def self.alias_method_chain(*args)
17
+ #Does nothing
18
+ end
19
+
20
+ include PgComment::SchemaDumper
21
+
22
+ public :dump_comments
23
+ end
24
+
25
+ class Stream
26
+ attr_reader :stream_results
27
+
28
+ def puts(str = nil)
29
+ @stream_results ||= []
30
+ @stream_results << str unless str.nil?
31
+ end
32
+ end
33
+
34
+ def setup
35
+ @fake_table = 'my_table'
36
+ @expected = [" set_table_comment '#{@fake_table}', 'table comment'",
37
+ " set_column_comment '#{@fake_table}', 'c1', 'column1 comment'",
38
+ " set_column_comment '#{@fake_table}', 'c2', 'column2 comment'"].join("\n")
39
+ end
40
+
41
+ def test_dump_comments
42
+ sd = SchemaDumpContainer.new
43
+ stream = Stream.new
44
+ sd.dump_comments @fake_table, stream
45
+ assert_equal @expected, stream.stream_results[0]
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pg_comment
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arthur Shagall
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &15971340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *15971340
25
+ - !ruby/object:Gem::Dependency
26
+ name: test-unit
27
+ requirement: &15970820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *15970820
36
+ description: Adds helper methods to migrations and pulls out comments into schema.rb
37
+ email:
38
+ - arthur.shagall@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - LICENSE
46
+ - README.rdoc
47
+ - Rakefile
48
+ - lib/pg_comment.rb
49
+ - lib/pg_comment/connection_adapters/abstract/schema_definitions.rb
50
+ - lib/pg_comment/connection_adapters/abstract/schema_statements.rb
51
+ - lib/pg_comment/connection_adapters/postgresql_adapter.rb
52
+ - lib/pg_comment/migration/command_recorder.rb
53
+ - lib/pg_comment/railtie.rb
54
+ - lib/pg_comment/schema_dumper.rb
55
+ - lib/pg_comment/version.rb
56
+ - pg_comment.gemspec
57
+ - test/fake_connection.rb
58
+ - test/postgre_sql_adapter_test.rb
59
+ - test/schema_dumper_test.rb
60
+ homepage: https://github.com/albertosaurus/pg_comment
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project: pg_comment
80
+ rubygems_version: 1.8.10
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Postgres Comments for Rails
84
+ test_files: []