Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for json comment #10

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Install
gem install active_record-comments
```

Usage
Usage (Default commenter)
=====

```ruby
Expand All @@ -26,6 +26,25 @@ result = ActiveRecord::Comments.comment("account cleanup") do
end
```

Usage (Json commenter)
=====

```ruby
require "active_record/comments"

ActiveRecord::Comments.configure do |config|
config.enable_json_comment = true
end

# => SELECT ... /* {"user":"123"} */
result = ActiveRecord::Comments.comment(user: "123") { User.where("x like y").count }

# => SELECT ... /* {"account":"1","service":"commenter"} */
result = ActiveRecord::Comments.comment(account: "1") do
ActiveRecord::Comments.comment(service: "commenter") { User.where("x like y").count }
end
```

Author
======
[Michael Grosser](https://grosser.it)<br/>
Expand Down
26 changes: 15 additions & 11 deletions lib/active_record/comments.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
require "active_record/comments/configuration"
require "active_record/comments/execute_with_comments"
require "active_record/comments/json_commenter"
require "active_record/comments/simple_commenter"
require "active_record/comments/version"
require "active_record"

module ActiveRecord
module Comments
class << self
def comment(comment)
current_comments << comment
yield
ensure
current_comments.pop
def comment(comment, &block)
commenter.comment(comment, &block)
end

def with_comment_sql(sql)
return sql unless comment = current_comment
"#{sql} /* #{comment} */"
commenter.with_comment_sql(sql)
end

private
def current_comments
Thread.current[:ar_comments] ||= []

def commenter
configuration.enable_json_comment ? json_commenter : simple_commenter
end

def json_commenter
@json_commenter ||= JsonCommenter.new
end

def current_comment
current_comments.join(" ") if current_comments.present?
def simple_commenter
@simple_commenter ||= SimpleCommenter.new
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/active_record/comments/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module ActiveRecord
module Comments
Configuration = Struct.new(:enable_json_comment)

class << self
def configure
yield(configuration)
end

private

def configuration
@configuration ||= Configuration.new(false)
end
end
end
end
35 changes: 35 additions & 0 deletions lib/active_record/comments/json_commenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require "json"

module ActiveRecord
module Comments
class JsonCommenter
def comment(comment)
return yield unless comment.is_a?(Hash)

begin
orig = current_comments.dup
current_comments.merge!(comment)
yield
ensure
current_comments.replace(orig)
end
end

def with_comment_sql(sql)
return sql unless comment = current_comment

"#{sql} /* #{comment} */"
end

private

def current_comments
Thread.current[:ar_json_comment] ||= {}
end

def current_comment
current_comments.to_json if current_comments.present?
end
end
end
end
28 changes: 28 additions & 0 deletions lib/active_record/comments/simple_commenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module ActiveRecord
module Comments
class SimpleCommenter
def comment(comment)
current_comments << comment
yield
ensure
current_comments.pop
end

def with_comment_sql(sql)
return sql unless comment = current_comment

"#{sql} /* #{comment} */"
end

private

def current_comments
Thread.current[:ar_comments] ||= []
end

def current_comment
current_comments.join(" ") if current_comments.present?
end
end
end
end
89 changes: 89 additions & 0 deletions spec/active_record/comments/json_commenter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require "spec_helper"

describe ActiveRecord::Comments::JsonCommenter do
subject(:commenter) { ActiveRecord::Comments::JsonCommenter.new }

describe "#current_comment" do
it "is empty when not a hash" do
commenter.comment("xxx") {}
expect(commenter.send(:current_comment)).to eq(nil)
end

it "is filled when called with hash" do
result = nil
commenter.comment(foo: "bar") do
result = commenter.send(:current_comment)
end
expect(result).to eq('{"foo":"bar"}')
end

it "concatenates to json when multiple comments" do
result = nil
commenter.comment(foo: "bar") do
commenter.comment(hello: "world") do
result = commenter.send(:current_comment)
end
end
expect(result).to eq('{"foo":"bar","hello":"world"}')
end

it "merges existing hash key" do
result = nil
commenter.comment(foo: "bar") do
commenter.comment(foo: "world") do
result = commenter.send(:current_comment)
end
end
expect(result).to eq('{"foo":"world"}')
end

it "removes comment when its block ends" do
result = nil
commenter.comment(foo: "bar") do
commenter.comment(hello: "world") {}
result = commenter.send(:current_comment)
end
expect(result).to eq('{"foo":"bar"}')
end

it "does not removes comment when its block ends and the key already exist" do
result = nil
commenter.comment(foo: "bar") do
commenter.comment(foo: "world") {}
result = commenter.send(:current_comment)
end
expect(result).to eq('{"foo":"bar"}')
end
end

describe "#comment" do
it "returns results" do
expect(commenter.comment(foo: "bar") { 1 }).to eq(1)
end
end

describe "#with_comment_sql" do
it "returns sql with single k/v pair comment" do
result = nil
commenter.comment(foo: "bar") do
result = commenter.with_comment_sql("SELECT * FROM User")
end
expect(result).to eq('SELECT * FROM User /* {"foo":"bar"} */')
end

it "returns sql with multiple k/v pair comment" do
result = nil
commenter.comment({foo: "bar", hello: "world"}) do
commenter.comment(hello: "foo") do
result = commenter.with_comment_sql("SELECT * FROM User")
end
end
expect(result).to eq('SELECT * FROM User /* {"foo":"bar","hello":"foo"} */')
end

it "returns sql without comments" do
result = commenter.with_comment_sql("SELECT * FROM User")
expect(result).to eq("SELECT * FROM User")
end
end
end
60 changes: 60 additions & 0 deletions spec/active_record/comments/simple_commenter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require "spec_helper"

describe ActiveRecord::Comments::SimpleCommenter do
subject(:commenter) { ActiveRecord::Comments::SimpleCommenter.new }

describe "#current_comment" do
it "is empty when not called" do
commenter.comment("xxx") {}
expect(commenter.send(:current_comment)).to eq(nil)
end

it "is filled when called" do
result = nil
commenter.comment("xxx") do
result = commenter.send(:current_comment)
end
expect(result).to eq("xxx")
end

it "concatenates multiple comments" do
result = nil
commenter.comment("xxx") do
commenter.comment("yyy") do
result = commenter.send(:current_comment)
end
end
expect(result).to eq("xxx yyy")
end

it "removes comment when its block ends" do
result = nil
commenter.comment("xxx") do
commenter.comment("yyy") {}
result = commenter.send(:current_comment)
end
expect(result).to eq("xxx")
end
end

describe "#comment" do
it "returns results" do
expect(commenter.comment("xxx") { 1 }).to eq(1)
end
end

describe "#with_comment_sql" do
it "returns sql with comments" do
result = nil
commenter.comment("xxx") do
result = commenter.with_comment_sql("SELECT * FROM User")
end
expect(result).to eq('SELECT * FROM User /* xxx */')
end

it "returns sql without comments" do
result = commenter.with_comment_sql("SELECT * FROM User")
expect(result).to eq("SELECT * FROM User")
end
end
end
Loading