Skip to content

ankane/active_median

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ActiveMedian

Median and percentile for Active Record, Mongoid, arrays, and hashes

Supports:

  • PostgreSQL
  • SQLite
  • MariaDB
  • MySQL (with an extension)
  • SQL Server
  • MongoDB

🔥 Uses native functions for blazing performance

Build Status

Getting Started

Add this line to your application’s Gemfile:

gem "active_median"

For MySQL, also follow these instructions.

Models

Median

Item.median(:price)

Percentile

Request.percentile(:response_time, 0.95)

Works with grouping, too

Order.group(:store_id).median(:total)

Arrays and Hashes

Median

[1, 2, 3].median

Percentile

[1, 2, 3].percentile(0.95)

You can also pass a block

{a: 1, b: 2, c: 3}.median { |k, v| v }

Additional Instructions

MySQL

MySQL requires the PERCENTILE_CONT function from udf_infusion. To install it, do:

git clone https://github.com/infusion/udf_infusion.git
cd udf_infusion
./configure --enable-functions="percentile_cont"
make
sudo make install
mysql <options> < load.sql

SQLite

Improve performance with SQLite with an extension. Download percentile.c and follow the instructions for compiling loadable extensions for your platform.

On Linux, use:

gcc -g -fPIC -shared -lsqlite3 percentile.c -o percentile.so

On Mac, use:

gcc -g -fPIC -dynamiclib -L/usr/local/opt/sqlite/lib -lsqlite3 percentile.c -o percentile.dylib

To load it in Rails, create an initializer with:

db = ActiveRecord::Base.connection.raw_connection
db.enable_load_extension(1)
db.load_extension("percentile.so") # or percentile.dylib
db.enable_load_extension(0)

Upgrading

0.3.0

ActiveMedian 0.3.0 protects against unsafe input by default. For non-attribute arguments, use:

Item.median(Arel.sql(known_safe_value))

Also, percentiles are now supported with SQLite. Use the percentile extension instead of extension-functions.

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/ankane/active_median.git
cd active_median
bundle install

# Postgres
createdb active_median_test
bundle exec rake test

# SQLite
ADAPTER=sqlite3 BUNDLE_GEMFILE=gemfiles/sqlite3.gemfile bundle exec rake test

# MariaDB and MySQL (for MySQL, install the extension first)
mysqladmin create active_median_test
ADAPTER=mysql2 BUNDLE_GEMFILE=gemfiles/mysql2.gemfile bundle exec rake test

# SQL Server
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=YourStrong!Passw0rd' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest
docker exec -it <container-id> /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P YourStrong\!Passw0rd -Q "CREATE DATABASE active_median_test"
ADAPTER=sqlserver BUNDLE_GEMFILE=gemfiles/sqlserver.gemfile bundle exec rake test

# MongoDB
BUNDLE_GEMFILE=gemfiles/mongoid7.gemfile bundle exec rake test

About

Median and percentile for Active Record, Mongoid, arrays, and hashes

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages