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

Suggest add update_all and destroy_all methods #461

Open
vincar opened this issue Apr 1, 2022 · 0 comments
Open

Suggest add update_all and destroy_all methods #461

vincar opened this issue Apr 1, 2022 · 0 comments

Comments

@vincar
Copy link

vincar commented Apr 1, 2022

I love active_record in ruby, and I extend it like this

class Granite::Query::Builder(Model)
  private getter adapter : Granite::Adapter::Base = Model.adapter

  def update_all(**attributes)
    return if attributes.empty?

    assemble = self.assembler

    params = attributes.map do |key, value|
      "#{quote(key.to_s)}=#{assemble.add_parameter(value)}"
    end

    where = assemble.where
    args = assemble.numbered_parameters

    sql = "UPDATE #{quoted_table_name} SET #{params.join(", ")} #{where}"    

    elapsed_time = Time.measure do
      adapter.open &.exec(sql, args: args)
    end

    adapter.log(sql, elapsed_time, args)
  end

  def destroy_all
    assemble = self.assembler
    where = assemble.where
    args = assemble.numbered_parameters

    sql = "DELETE FROM #{quoted_table_name} #{where}"

    elapsed_time = Time.measure do
      adapter.open &.exec(sql, args: args)
    end

    adapter.log(sql, elapsed_time, args)
  end

  private def quote(term : String)
    adapter.quote(term)
  end

  private def quoted_table_name
    quote(assembler.table_name.to_s)
  end
end

module Granite::Querying
  def update_all(**attributes)
    return if attributes.empty?

    placeholder = case adapter.class.to_s
      when "Granite::Adapter::Pg" then "$"
      else "?"
    end

    params = [] of String
    args =  [] of Granite::Columns::Type

    attributes.each_with_index do |field, value, i|
      ch = placeholder == "?" ? "?" : "$#{i + 1}"
      params << "#{quote(field.to_s)}=#{ch}"
      args << value
    end

    sql = "UPDATE #{quoted_table_name} SET #{params.join(", ")}"
    
    elapsed_time = Time.measure do
      adapter.open &.exec(sql, args: args)
    end

    adapter.log(sql, elapsed_time, args)
  end

  def destroy_all
    clear
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants