module WithAdvisoryLock
  class PostgreSQL < Base
    # See http://www.postgresql.org/docs/9.1/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
    def try_lock
      execute_successful?('pg_try_advisory_lock')
    end

    def release_lock
      execute_successful?('pg_advisory_unlock')
    end

    def execute_successful?(pg_function)
      sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name}"
      result = connection.select_value(sql)
      # MRI returns 't', jruby returns true. YAY!
      (result == 't' || result == true)
    end

    # PostgreSQL wants 2 32bit integers as the lock key.
    def lock_keys
      @lock_keys ||= begin
        [stable_hashcode(lock_name), ENV['WITH_ADVISORY_LOCK_PREFIX']].map do |ea|
          # pg advisory args must be 31 bit ints
          ea.to_i & 0x7fffffff
        end
      end
    end
  end
end


module WithAdvisoryLock
  class PostgreSQL < Base
    # See http://www.postgresql.org/docs/9.1/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
    def try_lock
      execute_successful?('pg_try_advisory_lock')
    end

    def release_lock
      execute_successful?('pg_advisory_unlock')
    end

    def execute_successful?(pg_function)
      sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name} /* #{lock_name} */"
      result = connection.select_value(sql)
      # MRI returns 't', jruby returns true. YAY!
      (result == 't' || result == true)
    end

    # PostgreSQL wants 2 32bit integers as the lock key.
    def lock_keys
      @lock_keys ||= begin
        [stable_hashcode(lock_name), ENV['WITH_ADVISORY_LOCK_PREFIX']].map do |ea|
          # pg advisory args must be 31 bit ints
          ea.to_i & 0x7fffffff
        end
      end
    end
  end
end


Add SQL comment to original lock string for PostgreSQL
Add SQL comment to original lock string for PostgreSQL

The PostgreSQL implementation requires translating the user-specified
lock string into a pair of 32 bit numbers, which makes the lock and
unlock statements opaque in the SQL logs.

To aid debugging, add a SQL comment containing the original lock string.
The comment will be removed from the input by the PostgreSQL parser, but
it will still show up in logs.