Git Product home page Git Product logo

pp_sql's Introduction

PpSql

Version               Codacy Badge          Reviewed by Hound

Replace standard ActiveRecord#to_sql method with anbt-sql-formatter gem for pretty SQL code output in console. Rails log will be formatted also. Example output:

log

Or in console

console

Require

Ruby 2.4+

Rails

Rails 5.0+ (optional), will be injected automatically

Legacy

You can use version ~> 0.2 of this gem with Ruby 2.2, 2.3 and/or Rails 4.0, 4.1

Usage

Post.first.to_sql

for easy and clean usage with custom string you can use:

class MyAwesomeDecoratedString < String
  include PpSql::ToSqlBeautify
end

Installation

add in Gemfile

gem 'pp_sql', group: :development

And then execute:

bundle

With other formatters

If you are pry user, or use custom output formatter, use puts for output whitespaces, like puts User.all.to_sql, or use User.all.pp_sql.

With Rails

If you do not want to rewrite default #to_sql method you may specify PpSql.rewrite_to_sql_method=false in initializers.

You can also disable log formatting by specifying PpSql.add_rails_logger_formatting=false in initializers.

Add to Application record

I found usefull this trick:

class ApplicationRecord < ActiveRecord::Base
 include PpSql::ToSqlBeautify if defined?(Rails::Console)

 self.abstract_class = true
end

Supported by

jetbrains

Contributing

Running the tests requires sqlite. To run the tests for different combinations of dependency versions, run bundle exec appraisal install followed by bundle exec appraisal rake.

License

The gem is available as open source under the terms of the MIT License.

pp_sql's People

Contributors

ahmad19 avatar dputtick avatar indigolain avatar kalmanh avatar kvokka avatar tsubery avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pp_sql's Issues

No git tags

Any chance of adding git tags for each new version release? It's difficult to figure out which commit corresponds to each version on Rubygems.

Great gem btw. Thanks for creating it.

ArgumentError: wrong number of arguments (given 1, expected 2)

Ruby 2.4, Rails 5.1.3

Call User.find(373481379) in pry console. Get an error.

Stack trace:

Could not log "sql.active_record" event. ArgumentError: wrong number of arguments (given 1, expected 2)
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/log_subscriber.rb:50:in `render_bind'
/home/gambala/.rvm/gems/ruby-2.4.1/bundler/gems/pp_sql-fbe46d0df86d/lib/pp_sql.rb:79:in `block in sql'
/home/gambala/.rvm/gems/ruby-2.4.1/bundler/gems/pp_sql-fbe46d0df86d/lib/pp_sql.rb:78:in `map'
/home/gambala/.rvm/gems/ruby-2.4.1/bundler/gems/pp_sql-fbe46d0df86d/lib/pp_sql.rb:78:in `sql'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/subscriber.rb:99:in `finish'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/log_subscriber.rb:83:in `finish'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/fanout.rb:102:in `finish'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/fanout.rb:46:in `block in finish'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/fanout.rb:46:in `each'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/fanout.rb:46:in `finish'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:42:in `finish_with_state'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:27:in `instrument'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/postgresql_adapter.rb:612:in `exec_no_cache'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/postgresql_adapter.rb:601:in `execute_and_clear'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:79:in `exec_query'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract/database_statements.rb:371:in `select'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract/database_statements.rb:42:in `select_all'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract/query_cache.rb:97:in `select_all'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/querying.rb:39:in `find_by_sql'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/statement_cache.rb:107:in `execute'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activerecord-5.1.3/lib/active_record/core.rb:187:in `find'
(pry):6:in `__pry__'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:355:in `eval'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:355:in `evaluate_ruby'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:323:in `handle_line'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:242:in `catch'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:242:in `block in eval'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:241:in `catch'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_instance.rb:241:in `eval'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:77:in `block in repl'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:67:in `loop'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:67:in `repl'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:38:in `block in start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/input_lock.rb:61:in `__with_ownership'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/input_lock.rb:79:in `with_ownership'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:38:in `start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/repl.rb:15:in `start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/pry-0.10.4/lib/pry/pry_class.rb:169:in `start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/commands/console/console_command.rb:62:in `start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/commands/console/console_command.rb:17:in `start'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/commands/console/console_command.rb:85:in `perform'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/thor-0.19.4/lib/thor/command.rb:27:in `run'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/thor-0.19.4/lib/thor/invocation.rb:126:in `invoke_command'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/thor-0.19.4/lib/thor.rb:369:in `dispatch'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/command/base.rb:63:in `perform'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/command.rb:44:in `invoke'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/railties-5.1.3/lib/rails/commands.rb:16:in `<top (required)>'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/bootsnap-1.1.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/bootsnap-1.1.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:292:in `block in require'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:258:in `load_dependency'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:292:in `require'
/home/gambala/git/melp-rails/bin/rails:9:in `<top (required)>'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/bootsnap-1.1.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `load'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/bootsnap-1.1.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `load'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:286:in `block in load'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:258:in `load_dependency'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:286:in `load'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/commands/rails.rb:6:in `call'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/command_wrapper.rb:38:in `call'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:201:in `block in serve'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:171:in `fork'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:171:in `serve'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:141:in `block in run'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:135:in `loop'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application.rb:135:in `run'
/home/gambala/.rvm/gems/ruby-2.4.1/gems/spring-2.0.2/lib/spring/application/boot.rb:19:in `<top (required)>'
/home/gambala/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
/home/gambala/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
-e:1:in `<main>'

P.S. On some queries if I call .to_sql method after query โ€” I get properly formatted sql. But User.find(373481379).to_sql gives me the same error.

Error in Rails 4.2

It looks like this is designed for Rails 5 - maybe add that to the README under Require?

When I run it on a Rails 4.2, e.g.:

Album.where(id: 1)

It shows an error, the beginning of which is:

Could not log "sql.active_record" event. ArgumentError: wrong number of arguments (1 for 2)
["/Users/michaelkeenan/.rvm/gems/ruby-2.2.3@maenad/gems/activerecord-4.2.7/lib/active_record/log_subscriber.rb:23:in `render_bind'"
"/Users/michaelkeenan/.rvm/gems/ruby-2.2.3@maenad/gems/pp_sql-0.2.0/lib/pp_sql.rb:41:in `block in sql'"

Checking the difference between the Rails 5 version of render_bind and the Rails 4.2 version, I see that there's two arguments in Rails 4.2, and one argument in 5. So (though I haven't tested it specifically), that'll be why this is occurring.

Similarly, when I try:

Album.all

I get this error:

Could not log "sql.active_record" event. NoMethodError: undefined method `colorize_payload_name' for #<ActiveRecord::LogSubscriber:0x007fccef1f2e08>
["/Users/michaelkeenan/.rvm/gems/ruby-2.2.3@maenad/gems/pp_sql-0.2.0/lib/pp_sql.rb:44:in `sql'"

colorize_payload_name is a private method in the Rails 5 log_subscriber, but doesn't exist in 4.2.

JSON query broken due to extra space

We've encountered a weird bug here when using a JSONB column.

if you have a where clause like

.where("event_metadata.metadata -> 'replaced' != 'true'")

The query will be replaced by

event_metadata.metadata - > 'replaced' != 'true'

notice the extra space between the - and >

This prevents the query from being run.

Why is rails required?

In my opinion, rails should not be a required dependency. Two approaches one could take for this.

  1. Move that to a developmental dependency, and simply place a conditional require in your entrypoint file (pp_sql.rb) like:
# This is a common practice among gems that support `rails` "injection"
require 'pp_sql/railtie.rb' if defined?(Rails::Railtie)
  1. Create another (very simple) gem (which can exist in the same repo if desired, with a pp_sql-rails.gemspec) called pp_sql-rails, which has a dependency on pp_sql and rails, and this is where you'd put the railtie injection bit.

That way, folks who don't need all of rails (many gems just require active_record, for example), and have the benefit of pretty printing sql, without the weight of rails! This also opens up pp_sql for inclusion in other frameworks, such as Sinatra, or Hanami!

Thanks for your work on pp_sql. I'm grateful someone has made this contribution.

This gem breaks postgres full text search functionality

After hours of debugging and no finding no clue why search is not working in my local env, finally when i commneted out this gem out of my dev gem group my postgres full text search queries started to working, before that i was having this issue

Started GET "/api/search?auth=P2efdRFjNK1nJteqvf0h8fo0d4GyPWw1&keyword=finans" for 172.31.0.1 at 2020-06-16 15:20:47 +0000
Cannot render console from 172.31.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Api::SearchController#content as */*
  Parameters: {"auth"=>"xxxxxxxx", "keyword"=>"finans"}
  User Load (0.3ms)  SELECT
    "users" . *
  FROM
    "users"
  WHERE
    "users" . "session_token" = $1
  ORDER BY
    "users" . "id" ASC LIMIT 1  [["session_token", "P2efdRFjNK1nJteqvf0h8fo0d4GyPWw1"]]
Completed 500 Internal Server Error in 39ms (ActiveRecord: 0.3ms)

ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  syntax error at or near ":"
LINE 9:               "audio_clips" . "title" : : text
                                              ^
: SELECT COUNT(*) FROM "audio_clips" INNER JOIN (SELECT
    "audio_clips" . "id" AS pg_search_id
    ,(
      ts_rank (
        (
          to_tsvector (
            'simple'
            ,COALESCE (
              "audio_clips" . "title" : : text
              ,''
            )
          ) || to_tsvector (
            'simple'
            ,COALESCE (
              pg_search_b229fd995799cea4ca76c4.pg_search_93f916f001b6b057ee2922 : : text
              ,''
            )
          )
        )
        ,(
          to_tsquery (
            'simple'
            ,''' ' || 'finans' || ' '''
          )
        )
        ,0
      )
    ) AS rank
  FROM
    "audio_clips" LEFT OUTER JOIN (
      SELECT
          "audio_clips" . "id" AS id
          ,string_agg (
            "tags" . "name" : : text
            ,' '
          ) AS pg_search_93f916f001b6b057ee2922
        FROM
          "audio_clips" INNER JOIN "taggings"
            ON "taggings" . "audio_clip_id" = "audio_clips" . "id" INNER JOIN "tags"
            ON "tags" . "id" = "taggings" . "tag_id"
        GROUP BY
          "audio_clips" . "id"
    ) pg_search_b229fd995799cea4ca76c4
      ON pg_search_b229fd995799cea4ca76c4.id = "audio_clips" . "id"
  WHERE
    (
      (
        to_tsvector (
          'simple'
          ,COALESCE (
            "audio_clips" . "title" : : text
            ,''
          )
        ) || to_tsvector (
          'simple'
          ,COALESCE (
            pg_search_b229fd995799cea4ca76c4.pg_search_93f916f001b6b057ee2922 : : text
            ,''
          )
        )
      ) @@ (
        to_tsquery (
          'simple'
          ,''' ' || 'finans' || ' '''
        )
      )
    )) AS pg_search_627d4ee04ccb6d014d9a06 ON "audio_clips"."id" = pg_search_627d4ee04ccb6d014d9a06.pg_search_id WHERE ("audio_clips"."published" = $1 AND "audio_clips"."published" = $2 AND (audio_clips.publish_time < '2020-06-16 15:20:47.938365') AND "audio_clips"."published" = $3 AND ('2020-06-16 15:20:47.938575' < audio_clips.expires_at) AND "audio_clips"."category_id" IS NULL OR "audio_clips"."published" = $4 AND "audio_clips"."published" = $5 AND (audio_clips.publish_time < '2020-06-16 15:20:47.938365') AND "audio_clips"."published" = $6 AND ('2020-06-16 15:20:47.938575' < audio_clips.expires_at) AND ("audio_clips"."category_id" NOT IN (SELECT "category_unsubscriptions"."category_id" FROM "category_unsubscriptions" WHERE "category_unsubscriptions"."user_id" = $7)))):


  Rendered /usr/local/bundle/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (3.7ms)
  Rendered /usr/local/bundle/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.5ms)
  Rendered /usr/local/bundle/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.6ms)
  Rendered /usr/local/bundle/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (14.9ms)

Undefined method `one?' for 1:Integer

Hi,

I tried using this gem, and it does pretty format the SQL, but returns the following warning after each query

Could not log "sql.active_record" event. NoMethodError: undefined method `one?' for 1:Integer

I'm using Rails 5, on Ruby 2.4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.