ARFI
Warning
This project only supports PostgreSQL and MySQL databases. SQLite3 will be supported in the future as well as other databases supported by Rails.
Note
This project requires Ruby 3.1.0+, in future updated 2.6+ Ruby versions will be supported.
ARFI – ActiveRecord Functional Indexes
The ARFI gem provides the ability to create and maintain custom SQL functions for ActiveRecord models without switching
to structure.sql
(an SQL-based schema). You can use your own SQL functions in any part of the project, from migrations
and models to everything else. There is a working example in
the demo project. All instructions are described
in README. ARFI supports all types of database
architectures implemented in Rails, suitable for both working with single databases and for simultaneous work with
multiple databases in the same environment.
- ARFI
- Installation
- Usage
- Internal documentation
- CLI
- Project creation
- Index creation
- Index destroy
- Additional help
- Demo
- Library features
- Roadmap
- Commands
- Function creation
- Function destroy
- Options
-
--template
option -
--adapter
option
-
- Options
- Limitations
- Development
- Build from source
- Requirements
- Contributing
- Miscellaneous
- License
- Code of Conduct
Installation
Install the gem and add to the application's Gemfile by executing:
bundle add arfi
Usage
Internal documentation
Internal documentation available at https://github.com/unurgunite/arfi_docs.
CLI
ARFI uses Thor as a command line interface (CLI) instead of Rake, so it has a specific DSL.
Project creation
Firstly, run bundle exec arfi project create
to create a new project. This command will create db/functions
directory. ARFI uses db/functions
directory to store your SQL functions.
Function creation
Run bundle exec arfi f_idx create function_name
to create a new function. New SQL function will be created in
db/functions
directory under function_name_v01.sql
name. Edit your function and run bundle exec rails db:migrate
.
You can also use custom template for functions using --template
flag, this behaviour is described below.
Type bundle exec arfi f_idx help create
for additional info.
Function destroy
If you want to destroy your function, run bundle exec arfi f_idx destroy function_name [revision (default 1)]
. Please
note that after deleting the function, it will still be available, but if you run "bundle exec rails db:migrate" again,
an error will occur when using the function. Enter bundle exec arfi f_idx help destroy
for more information.
Additional help
Run bundle exec arfi
for additional help.
Demo
Demo available as separate project built with Rails 7.2 and PostgreSQL 14: https://github.com/unurgunite/poc_arfi_72. README is also available.
Library features
-
ARFI supports about all types of database initialization. It respects your database schema format and database configuration.
Task Completed db:migrate ✅ db:setup ✅ db:prepare ✅ db:schema:load ✅ db:reset ✅ db:setup:db_name In progress (see limitations) 🔄 -
Database support. ARFI supports PostgreSQL and MySQL databases and projects with multiple databases at the same time.
DB adapter Tested PostgreSQL ✅ MySQL ✅ SQLite3 In progress 🔄 -
Rails support
Rails version Tested 8 ✅ 7 ✅ 6 In progress 🔄
Roadmap
Custom template for SQL functions using--template
flag;Multidb support (Rails 6+ feature);- Add support for 4+ ActiveRecord;
- Add RSpec tests;
Add separate YARD doc page;Update CI/CD;- Add support for Ruby 2.6+.
Commands
ARFI has a set of commands to work with SQL functions. Type bundle exec arfi help
for additional help. As noted above,
ARFI uses Thor as a command line interface.
Function creation
ARFI supports creation of SQL functions. To create a new function, run bundle exec arfi f_idx create function_name
.
Also, there are some options:
Option name | Description | Possible values | Default value |
---|---|---|---|
--template |
use custom template | path within you filesystem | nil (will be used default template for each type of adapters) |
--adapter |
adapter specific function creation due to syntax differences between different RDBMS | postgresql, mysql | nil (function will be stored in generic db/functions ) |
Function destroy
ARFI supports destroy of SQL functions. To destroy a function, run
bundle exec arfi f_idx destroy function_name [revision (1 by default)]
.
Option name | Description | Possible values | Default value |
---|---|---|---|
--revision |
Function revision to destroy | Integer | 1 |
--adapter |
adapter specific function | postgresql, mysql | nil (function will be destroyed in generic db/functions ) |
Options
--template
option
This option is used for creating an SQL function. In this case, the function will not be created with the default template, but with user defined. There are some rules for templates:
-
The template must be written in a Ruby-compatible syntax: the function must be placed in a HEREDOC statement and must use interpolation for variables. If you need to take a more comprehensive approach to the issue of function generation, you can try using your own methods in the template file. No matter what you write there, the main rule is that your main method should return a string with a function template, as described below.
-
ARFI supports dynamic variables in templates, but only one at the moment. You need to specify
index_name
variable as below. In feature updated ARFI will support more variables. Here are default templates in ARFI for PostgreSQL and MySQL:PostgreSQL:
<<~SQL CREATE OR REPLACE FUNCTION #{index_name}() RETURNS TEXT[] LANGUAGE SQL IMMUTABLE AS $$ -- Function body here $$ SQL
MySQL:
<<~SQL CREATE FUNCTION #{index_name} () RETURNS return_type BEGIN -- Function body here END; SQL
-
By default ARFI uses PostgreSQL template.
--adapter
option
This option is used both when destroying and when creating an SQL function. In this case, the function will not be
created in the default directory db/functions
, but in the child db/functions/#{adapter}
. Supported adapters:
postgresql
and mysql
, but there will be more in the future.
Limitations
Currently, ARFI has a limitation for db:setup:db_name
task due to the fact how Rails manage this rake task. More info
here: limitations. This command will work, but it is not recommended to use it. Note that this limitation applies
only to multi-db setup, default db:setup
will work as expected.
Development
Build from source
The manual installation includes installation via command line interface. it is practically no different from what happens during the automatic build of the project:
git clone https://github.com/unurgunite/arfi.git
cd arfi
bundle install
gem build arfi.gemspec
gem install arfi-0.5.1.gem
Also, you can run bin/setup
to automatically install everything needed.
Requirements
ARFI is built on top of the following gems:
Dependencies | Description |
---|---|
ActiveRecord | Used to patch ActiveRecord::Base module with new methods. |
Rails | Used for fetching project settings (database connection settings, Rails environment, etc.) |
Thor | For CLI development. |
Rubocop | For static code analysis. |
Rake | For patching built-in Rails Rake tasks. |
Steep | For static type checking. |
RBS | For static type checking. |
YARD | For generating documentation. |
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/unurgunite/arfi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
Miscellaneous
ARFI is highly inspired by https://github.com/teoljungberg/fx project.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the ARFI project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.