Commit ff674e9f authored by Ohad Dahan's avatar Ohad Dahan

README edit, renamed nativepluck_raw to nativepluck

parent cb9aac31
......@@ -11,6 +11,7 @@
log/*.log
pkg/
test/dummy/*.txt
test/dummy/*.csv
test/dummy/debug*.rb
test/dummy/db/*.sqlite3
test/dummy/db/*.sqlite3-journal
......
# Nativepluck
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/nativepluck`. To experiment with that code, run `bin/console` for an interactive prompt.
TODO: Delete this and the text above, and describe your gem
This Gem is aimed to replace `pluck` for anyone using PostgreSQL.
By using native PostgreSQL casting we get a significant memory and time saving.
## Installation
......@@ -22,7 +21,23 @@ Or install it yourself as:
## Usage
TODO: Write usage instructions here
* If you want to use it as an `ActiveRecord` method, add `include Nativepluck` inside your model.<br>
In this usage mode (more examples in `test/dummy/test/models/genericmodel_test.rb`):
`ModelName.nativepluck(:id, order: {id: :asc} , limit: limit)`<br>
This will generate a query based on your parameters and use native PG casting.
* If you have more complex queries that we don't currently support, such as `join`.<br>
You can take an existing query, for example:<br>
`ModelName.where('id > 1').limit(1).joins(:some_other_model).pluck(:id)`<br>
Change `pluck` to `select`:<br>
`ModelName.where('id > 1').limit(1).joins(:some_other_model).select(:id)`<br>
And insert into `Nativepluck.nativepluck( ModelName.where('id > 1').limit(1).joins(:some_other_model).select(:id) )`<br>
Inside, we'll run `to_sql` on the supplied query and run it.<br>
You can also insert a raw `SQL` string such as:<br>
`Nativepluck.nativepluck("SELECT id FROM ModelNames WHERE id > 1")`<br>
## Benchmarks
## Development
......
......@@ -35,7 +35,7 @@ module Nativepluck
ActiveRecord::Base.connection.raw_connection.type_map_for_queries = Nativepluck.original_type_map_for_queries
end
def self.nativepluck_raw(input)
def self.nativepluck(input)
begin
sql = input.respond_to?(:to_sql) ? input.to_sql : input
Nativepluck.set_pg_native_casters
......
......@@ -19,15 +19,15 @@ module BenchMarks
results = Genericmodel.nativepluck(attribute_name, limit: limit)
end
##################################################################################################
Nativepluck.nativepluck_raw(Genericmodel.limit(limit).select(attribute_name))
Nativepluck.nativepluck(Genericmodel.limit(limit).select(attribute_name))
reports[:nativepluck_raw_to_sql][attribute_name] = MemoryProfiler.report do
results = Nativepluck.nativepluck_raw(Genericmodel.limit(limit).select(attribute_name))
results = Nativepluck.nativepluck(Genericmodel.limit(limit).select(attribute_name))
end
##################################################################################################
sql = Genericmodel.limit(limit).select(attribute_name).to_sql
Nativepluck.nativepluck_raw(sql)
Nativepluck.nativepluck(sql)
reports[:nativepluck_raw_string][attribute_name] = MemoryProfiler.report do
results = Nativepluck.nativepluck_raw(sql)
results = Nativepluck.nativepluck(sql)
end
##################################################################################################
end
......
......@@ -13,8 +13,8 @@ module BenchMarks
x.config(time: 5, warmup: 1)
x.report("pluck | #{limit} | #{attribute_name}") { Genericmodel.limit(limit).pluck(attribute_name) }
x.report("nativepluck | #{limit} | #{attribute_name}") { Genericmodel.nativepluck(attribute_name, limit: limit) }
x.report("nativepluck_raw :to_sql | #{limit} | #{attribute_name}") { Nativepluck.nativepluck_raw(Genericmodel.limit(limit).select(attribute_name)) }
x.report("nativepluck_raw SQL_RAW | #{limit} | #{attribute_name}") { Nativepluck.nativepluck_raw(sql_raw) }
x.report("nativepluck_raw :to_sql | #{limit} | #{attribute_name}") { Nativepluck.nativepluck(Genericmodel.limit(limit).select(attribute_name)) }
x.report("nativepluck_raw SQL_RAW | #{limit} | #{attribute_name}") { Nativepluck.nativepluck(sql_raw) }
x.compare!
end
end
......
......@@ -3,6 +3,7 @@ require 'test_helper'
# We use order in all tests to prevent tests from failing due to DB fetching rows in a different order
#
class GenericmodelTest < ActiveSupport::TestCase
##########################################################
test 'pluck_each_attribute' do
failed = []
Genericmodel.attribute_types.each do |attr_name, attr_type|
......@@ -12,7 +13,7 @@ class GenericmodelTest < ActiveSupport::TestCase
end
assert(failed.empty?, "#{__method__}:: pluck != nativepluck for attributes : #{failed.join(', ')}")
end
##########################################################
test 'pluck_permutations' do
row_limit = 100
failed = []
......@@ -23,8 +24,7 @@ class GenericmodelTest < ActiveSupport::TestCase
end
assert(failed.empty?, "#{__method__}:: pluck != nativepluck for attributes : #{failed.join(', ')}")
end
##########################################################
test 'test_limit' do
Range.new(1,100).step(rand(5) + 1).each do |limit|
pluck = Genericmodel.limit(limit).order(id: :asc).pluck(:id)
......@@ -32,8 +32,7 @@ class GenericmodelTest < ActiveSupport::TestCase
assert(pluck == nativepluck, "#{__method__}:: pluck != nativepluck for column :id and limit #{limit}")
end
end
##########################################################
test 'test_offset' do
row_limit = 100
Range.new(1,100).step(rand(5) + 1).each do |offset|
......@@ -42,16 +41,34 @@ class GenericmodelTest < ActiveSupport::TestCase
assert(pluck == nativepluck, "#{__method__}:: pluck != nativepluck for column :id and offset #{offset}")
end
end
##########################################################
test 'test_group_by' do
row_limit = 100
pluck = Genericmodel.limit(row_limit).order(id: :asc).group(:id).pluck(:id)
nativepluck = Genericmodel.nativepluck(:id, order: {id: :asc} , group: [:id], limit: row_limit )
assert(pluck == nativepluck, "#{__method__}:: pluck != nativepluck")
end
##########################################################
test 'Nativepluck_nativepluck_query' do
row_limit = 100
failed = []
Genericmodel.attribute_types.each do |attr_name, attr_type|
pluck = Genericmodel.limit(row_limit).order(id: :asc).pluck(attr_name)
nativepluck = Nativepluck.nativepluck(Genericmodel.limit(row_limit).order(id: :asc).select(attr_name))
failed << attr_name if pluck != nativepluck
end
assert(failed.empty?, "#{__method__}:: pluck != nativepluck for attributes : #{failed.join(', ')}")
end
##########################################################
test 'Nativepluck_nativepluck_string' do
row_limit = 100
failed = []
Genericmodel.attribute_types.each do |attr_name, attr_type|
pluck = Genericmodel.limit(row_limit).order(id: :asc).pluck(attr_name)
nativepluck = Nativepluck.nativepluck(Genericmodel.limit(row_limit).order(id: :asc).select(attr_name).to_sql)
failed << attr_name if pluck != nativepluck
end
assert(failed.empty?, "#{__method__}:: pluck != nativepluck for attributes : #{failed.join(', ')}")
end
##########################################################
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment