Crystal ORM using ActiveRecord pattern with flexible query DSL

Releases:

  • v0.7.1 - February 9, 2019
  • v0.7.0 - January 8, 2019
  • v0.6.2 - October 23, 2018
  • v0.6.1 - September 7, 2018
  • v0.6.0 - July 6, 2018

Dependencies:

Owner:

Jennifer Build Status Latest Release Docs

ActiveRecord pattern implementation for Crystal with a powerful query DSL, validation, relationship definition, translation and migration mechanism.

Installation

Add this to your application's shard.yml:

dependencies:
  jennifer:
    github: imdrasil/jennifer.cr
    version: "~> 0.7.1"

Requirements

  • you need to choose one of existing drivers for your db: mysql or postgres; sqlite3 adapter automatically installs required driver for itself;
  • crystal >= 0.26.1.

Usage

Jennifer allows you to maintain everything for your models - from db migrations and field mapping to callbacks and building queries. For detailed information see the guide and API documentation.

Migration

To start using Jennifer you'll first need to generate a migration:

$ crystal sam.cr -- generate:migration CreateContact

then fill the created migration file with content:

class CreateContact < Jennifer::Migration::Base
  def up
    # Postgres requires to create specific enum type
    create_enum(:gender_enum, ["male", "female"])
    create_table(:contacts) do |t|
      t.string :name, {:size => 30}
      t.integer :age
      t.integer :tags, {:array => true}
      t.field :gender, :gender_enum
      t.timestamps
    end
  end

  def down
    drop_table :contacts
    drop_enum(:gender_enum)
  end
end

and run

$ crystal sam.cr -- db:setup

to create the database and run the newly created migration.

For command management Jennifer uses Sam.

Model

Jennifer provides next features:

  • flexible model schema definition
  • relationship definition (belongs_to, has_many, has_one, has_and_belongs_to_many)
  • validation
  • model-specific query scope definition
  • callbacks
  • view support
  • translations

Hers is model example:

class Contact < Jennifer::Model::Base
  with_timestamps
  mapping(
    id: Primary32, # is an alias for Int32? primary key
    name: String,
    gender: { type: String?, default: "male" },
    age: { type: Int32, default: 10 },
    description: String?,
    created_at: Time?,
    updated_at: Time?
  )

  has_many :facebook_profiles, FacebookProfile
  has_and_belongs_to_many :countries, Country
  has_and_belongs_to_many :facebook_many_profiles, FacebookProfile, join_foreign: :profile_id
  has_one :passport, Passport

  validates_inclusion :age, 13..75
  validates_length :name, minimum: 1, maximum: 15
  validates_with_method :name_check

  scope :older { |age| where { _age >= age } }
  scope :ordered { order(name: :asc) }

  def name_check
    return unless description && description.not_nil!.size > 10
    errors.add(:description, "Too large description")
  end
end

More details you can find in the documentation.

Query DSL

Jennifer allows you to query the db using a flexible DSL:

Contact.all.left_join(Passport) { _contact_id == _contact__id }
            .order(id: :asc).order(Contact._name.asc.nulls_last)
            .with(:passport).to_a
Contact.all.eager_load(:countries).where { __countries { _name.like("%tan%") } }
Contact.all.group(:gender).group_avg(:age, PG::Numeric)

Much more about the query DSL can be found on the wiki page.

Versioning

Now that Jennifer is under heavy development, there could be many breaking changes. So please check the release notes to check if any of the changes may prevent you from using it. Also, until this library reaches a beta version, the next version rules will be followed:

  • all bugfixes, new minor features or (sometimes) ones that don't break the existing API will be added as a patch number (e.g. 0.3.4);

  • all breaking changes and new important features (as well as reaching a milestone) will be added by bumping the minor digit (0.4.0);

So even a patch version change could bring a lot of new stuff.

If there is a branch for the next release - it will be removed 1 month after the release. So please use them only as a hotfix or for experiments or contribution.

Test tips

The fastest way to rollback all changes in the DB after test case is by using a transaction. So add:

Spec.before_each do
  Jennifer::Adapter.adapter.begin_transaction
end

Spec.after_each do
  Jennifer::Adapter.adapter.rollback_transaction
end

to your spec_helper.cr. NB. you could simply use regular deleting or truncation, but a transaction will provide a 15x speed up (at least for postgres; mysql gets less impact).

This functions can be safely used only under test environment.

Development

Before developing any feature please create an issue where you describe your idea.

To setup dev environment run ./examples/setup.sh - it creates ./examples/database.yml configuration file. You can override there any values specific to your environment (like db user of password).

To create the databases:

# Postgres
$ make sam db:setup

# Mysql
$ DB=mysql make same db:setup

Running tests

All unit tests are written using core spec. Also in spec/spec_helper.cr some custom unit test matchers are defined. All migrations are under the ./examples/migrations directory.

The common way to run tests is just use using regular crystal spec tool:

$ crystal spec

PostgreSQL is used by default, but MySql is also supported while running tests by specifying environment variable DB=mysql:

In case you need to set the database user or password, use:

$ DB_USER=user DB_PASSWORD=pass crystal spec

Integration tests

Except unit tests there are also several integration tests. These tests checks possibility to compile and invoke jennifer functionality in some special edge cases (e.g. without defined models, migrations, etc.).

To run integration test just use standard spec runner:

$ crystal spec spec/integration/<test_name>.cr

Each test file is required to be invoked separately as it may have own configuration.

To run docker-related tests (by the way, all of them run only with mysql) firstly you should run docker container and specify environment variable DOCKER=1. For more details take a look at spec/integration/sam/* application files and examples/run_docker_mysql.sh docker boot script.

Documentation

Self documentation is not fully support yet but docs can be compiled using this shell script:

$ ./generate-docs.sh

NB. It also depends on then chosen adapter (postgres by default).

Similar shards

  • crecto - based on Phoenix's Ecto lib and follows the repository pattern
  • granite-orm - lightweight ORM focusing on mapping fields from request to your objects
  • topaz - inspired by AR ORM with migration mechanism
  • micrate - standalone database migration tool for crystal

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Please ask me before starting work on smth.

Contributors

  • imdrasil Roman Kalnytskyi - creator, maintainer

Changelog

Future release (--2019)

0.7.1 (09-02-2019)

QueryBuilder

  • #pluck, #update, #db_results, #results. #each_result_set and #find_in_batchesof Query respects #none (returns empty result if it has being called)
  • remove deprecated QueryObject constructor accepting array of options and #params

Model

  • fix mapping issue when all Generics are assumed as unions (#208)

Validation

  • allow passing multiple fields to .validates_uniqueness to validate combination uniqueness

Adapter

  • Mysql::SchemaProcessor now respects false as column default value
  • Postgres::SchemaProcessor now respects false as column default value

Config

  • introduce new configuration pool_size which sets max_idle_pool_size = max_pool_size = initial_pool_size to the given value; getter #pool_size returns #max_pool_size
  • postgres is no more default adapter

Migration

  • TableBuilder::Base::AllowedTypes alias includes Float64 and JSON::Any

0.7.0 (08-01-2019)

General

  • bump sam to "~> 0.3.0"
  • add sam command generate:model to generate model and related migration
  • move all logic regarding file generating to Jennifer::Generators space
  • add db:seed task as a placeholder seeding task
  • db:setup now invokes db:seed after db:migrate

QueryBuilder

  • add #and, #or and #xor shortcut methods to ExpressionBuilder
  • Criteria#in now accepts SQLNode as well
  • add Statement module with base abstract functionality needed for query string generating
  • ExpressionBuilder#g and #group now has no argument type restriction
  • Grouping#condition now can be of Statement type
  • Query includes Statement
  • Query#to_sql now is #as_sql, #select_args - #sql_args
  • Condition includes Statement
  • Executables#update accepts block expecting Hash(Symbol, Statement) to be returned
  • Executables#modify is removed in favor of new #update method accepting block
  • now LogicOperator is inherited from SQLNode
  • #delete and exists? of Executables do nothing when #do_nothing? is true
  • add Query#do_nothing?
  • add Query.null which returns Query.new.none
  • Join accepts Grouping for ON condition

Model

  • remove Base.build_params, Base.parameter_converter methods
  • remove ParameterConverter class
  • fix skipping generating default constructor byMapping.mapping when at least one field has default value and all others are nilable
  • stringified_type option is removed from the COLUMNS_METADATA
  • STIMapping#arguments_to_save & STIMapping#arguments_to_insert now respect field converter
  • Translation model now is includeable module
  • all class methods of Translation are moved to Translation::ClassMethods which is automatically extended by target class using included macro
  • #lookup_ancestors and #human_attribute_name methods of Translation are added
  • Errors#base now is type of Translation instead of Base
  • add Base#persisted?
  • now attribute-specific rendering for Resource#inspect is generated by .mapping
  • add polymorphic relation support for has_one, has_many and belongs_to relations
  • add :nodoc: for almost all generated relation methods (except #association)
  • add missing relation names for criterion in Relation::Base methods
  • add Relation::IPolymorphicBelongsTo, Relation::PolymorphicHasMany and Relation::PolymorphicHasOne
  • @new_record, @destroyed, @errors, changeset and relation attributes now is ignored by JSON::Serializable
  • add skip_validation argument to Authentication.with_authentication macro to specify whether validation should be added
  • add generating predicate method #{{attribute}}? for boolean attribute
  • allow Jennifer::Model::Base#attribute= to accept not only defined type but also Jennifer::DBAny
  • rename Base#update_attributes to Base#set_attributes

Validation

  • all validation macros now accept :if key; the value may be both Symbol name of a method to be called or expression
  • replace validation logic generated during a macro call with new validators usage: Validations::Absence, Validations::Acceptance, Validations::Confirmation, Validations::Exclusion, Validations::Format, Validations::Inclusion, Validations::Length, Validations::Numericality, Validations::Presence, Validations::Uniqueness
  • remove Jennifer::Validator in favour of Jennifer::Valdiations::Validator
  • all validators by default implement singleton pattern
  • all validation macros are moved to Jennifer::Validations::Macros

View

  • now attribute-specific rendering for Resource#inspect is generated by .mapping
  • add generating predicate method #{{attribute}}? for boolean attribute

Adapter

  • fix output stream for postgres schema dump
  • remove legacy postgres insert
  • add Adapter#foreign_key_exists?
  • add Mysql::SchameProcessor
  • now Base#schema_processor is abstract
  • add Postgres::SchemaProcessor#rename_table
  • SchemaProcessor now is abstract class
  • all builder methods are moved from SchemaProcessor class to TableBuilderBuilders module
  • fix syntax in SchemaProcessor#drop_foreign_key
  • all _query arguments in Base methods are renamed to query
  • Base.extract_arguments is removed
  • .delete, .exists and .count of BaseSQLGenerator now returns string
  • Postgres.bulk_insert is removed
  • Transaction#with_connection ensure to release connection
  • all sqlite3 related code are removed

Config

  • fix migration_failure_handler_method property from being global
  • add new property model_files_path presenting model directory (is used in a scope of model generating)
  • fix ignoring skip_dumping_schema_sql config

SqlGenerator

  • .select_clause now doesn't invoke .from_clause under the hood
  • .lock_clause adds whitespaces around lock statement automatically

Migration

  • remove Runner.generate and Runner::MIGRATION_DATE_FORMAT
  • TableBuilder::CreateTable#reference triggers #foreign_key and accepts polymorphic bool argument presenting whether additional type column should be added; for polymorphic reference foreign key isn't added

Exceptions

  • 'RecordNotFound' from QueryBuilder::Query#first! and QueryBuilder::Query#last! includes detailed parsed query

0.6.2 (23-10-2018)

General

  • add :nodoc: to all internal constants and generated methods (implementing standard ORM methods) from the macros

QueryBuilder

  • Query isn't extended by Ifrit
  • add OrderItem to describe order direction
  • add Criteria#order, Criteria#asc and Criteria#desc to create OrderItem
  • add Condition#eql? to compare with other condition or SQLNode (returns false)
  • add Criteria#eql?, Grouping#eql?, LogicOperator#eql?
  • add Query#order and Query#reorder with accepting OrderItem
  • now Query#order with block to expect a OrderItem
  • remove CriteriaContainer
  • QueryObject now is an abstract class
  • changed wording for the ArgumentError in #max, #min, #sum, #avg methods of Aggregation to "Cannot be used with grouping"
  • change Query#from(_from : String | Query) signature to Query#from(from : String | Query)

Model

  • #save and #update will return true when is called on an object with no changed fields (all before callbacks are invoked)
  • next Base methods become abstract: .primary_auto_incrementable?, .build_params, #destroy, #arguments_to_save, #arguments_to_insert
  • Base#_extract_attributes and Base#_sti_extract_attributes become private
  • all callback invocation methods become protected
  • next Resource methods become abstract: .primary, .field_count, .field_names, .columns_tuple, #to_h, #to_str_h
  • Resource isn't extended by Ifrit
  • regenerate .build_params for STI models
  • Scoping.scope(Symbol,QueryObject) now checks in runtime whether T of Jennifer::QueryBuilder::ModelQuery(T) responds to method named after the scope

View

  • Base#_after_initialize_callback becomes protected
  • Base#_extract_attributes becomes private

Adapter

  • fix custom port not used when accessing the Postgres database

Migration

  • TableBuilder::Base isn't extended by Ifrit
  • rename TableBuilder::ChangeTable#new_table_rename getter to #new_table_name
  • fix misuse of local variable in TableBuilder::ChangeTable#rename_table
  • TableBuilder::ChangeTable#change_column has next changes:
    • old_name argument renamed to name
    • new_name argument is replaced with option in options arguemnt hash
    • raise ArgumentError if both type and options[:sql_type] are nil
  • TableBuilder::ChangeTable#change_column raises ArgumentError if both type and options[:sql_type] are nil
  • TableBuilder::CreateTable#field data_type argument renamed to type
  • TableBuilder::CreateTable#timestamps creates fields with null: false by default
  • TableBuilder::CreateTable#add_index is removed in favour of #index
  • .pending_versions, .assert_outdated_pending_migrations and .default_adapter methods of Runnerbecome private
  • Runner.config is removed

0.6.1 (07-09-2018)

General

  • adds Time::Span to supported types

QueryBuilder

  • allows listing any SQLNode instance in SELECT clause (like raw sql or functions)
  • removes redundant SQLNode#sql_args_count
  • adds SQLNode#filterable? function which presents if node has filterable sql parameter
  • refactors Condition#sql_arg
  • adds Function base abstract class for defining custom sql functions
  • adds lower, upper, current_timestamp, current_date, current_time, now, concat, abs, ceil, floor, round
  • adds Join#filterable? and Query#filterable?
  • raise AmbiguousSQL when % symbol is found in the raw SQL (except %s)

Model

  • replaces mapping option numeric_converter with new converter
  • adds NumericToFloat64Converter and JSONConverter
  • now #to_h and #to_str_h use field getter methods
  • remove puts from JSONConverter#from_db

Adapter

  • propagate native DB::Error instead of wrapping it into BadQuery
  • manually release a connection when an exception occurs under the transaction

Config

  • set default max_pool_size to 1 and warn about danger of setting different max_pool_size, max_idle_pool_size and initial_pool_size

Migration

  • adds Migration::TableBuilder::CreateForeignKey & Migration::TableBuilder::DropForeignKey
  • adds Migration::Base#add_foreign_key & Migration::Base#drop_foreign_key
  • adds Migration::TableBuilder::ChangeTable#add_foreign_key & Migration::TableBuilder::ChangeTable#drop_foreign_key

Exceptions

  • add AmbiguousSQL - is raised when forbidden % symbol is used in the raw SQL

0.6.0 (06-07-2018)

General

  • adds support of crystal 0.25.0
  • removes time_zone dependency
  • removes requiring "inflector/string"
  • adds cloning to Time::Location & Time::Location::Zone
  • removes Ifrit.typed_hash and Ifrit.typed_array usage
  • presents "mapping types" which allows reusing common type definition
  • now Primary32 and Primary64 are mapping types (not aliases of Int32 and Int64)
  • removes accord dependency

QueryBuilder

  • allows nested eager loading in ModelQuery(T)#eager_load and ModelQuery(T)#include
  • all query eager loading methods are extracted to separate module QueryBuilder::EagerLoading which is included in QueryBuilder::IModelQuery

Model

  • introduces model virtual attributes
  • adds Mapping.build_params and ParameterConverter class for converting Hash(String, String) parameters to acceptable by model
  • allows to specify table prefix
  • all relations are stored in Base::RELATIONS
  • fixes building of sti objects using parent class
  • adds Jennifer::Model::Authentication module with authentication logic
  • fixes compile time issue with IRelation when app has no belongs-to relation defined
  • fixes bug with reading Int64 primary key
  • adds #inspect
  • adds numeric_converter mapping option for numeric postgres field
  • introduces new Jennifer::Model::Errors class replacing Accord::ErrorList which mimics analogic rails one a lot;
  • moves Translation::human_error method functionality to introduced Errors instance level
  • now next Resource static methods are abstract: actual_table_field_count, primary_field_name, build, all, superclass
  • Resource#inspect returns simplified version (only class name and object id)
  • Resource.all now is a macro method
  • fixes Model::Translation.lookup_ancestors from breaking at compilation time
  • now all built-in validations use attribute getter methods instead of variables

View

  • removes ExperimentalMapping#attributes_hash, ExperimentalMapping.strict_mapping?

Config

  • local_time_zone now is a Time::Location
  • local time zone is loaded using Time::Location.local as default value

SqlGenerator

  • replaces \n with whitespace character as query part separator

Migration

  • now migration version is taken from file name timestamp
  • Jennifer::Migration::Base.migrations returns a hash of version number => migration class instead of array of classes

0.5.1 (02-05-2018)

QueryBuilder

  • fixes bug with compiling application without defined any model (as a result no ModelQuery class is defined as well)
  • allows to pass sql arguments to left hand condition statement
  • fixes bug with invalid order direction type interpretation (#124)

Adapter

  • adds command interface layer for invoking console tool utilities (e.g. for dumping database schema)
  • adds docker command interface

Config

  • makes Config to realize singleton pattern instead of holding all data as class variables
  • adds flag to skip dumping database schema after running migrations
  • fixes connection port definition (#121)

0.5.0 (13-02-2018)

  • ifrit/core pact is required
  • adds i18n lib support
  • adds time_zone lib support

QueryBuilder

  • now #destroy uses #find_each
  • adds #patch and #patch! which invokes #update on each object
  • introduced CriteriaContainer to resolve issue with using Criteria object as a key for @order hash
  • all #as_sql methods now accept SQLGenerator class

Model

  • added methods #update & #update! which allows to massassign attributes and store object to the db
  • added support of localization lib (i18n)
  • added methods ::human_attribute_name, ::human_error and ::human to translate model attribute name, error message and model name
  • added own #valid? and #validate! methods - they performs validation and trigger callbacks each call
  • added #invalid? - doesn't trigger validation and callbacks
  • moved all validation error messages to yaml file
  • now %validates_with accepts oly one class and allows to pass extra arguments to validator class
  • %validate_presence_of is renamed to %validate_presence
  • adds new validation macros: %validate_absence, %validates_numericality, %validates_acceptance and %validates_confirmation
  • introduced own validator class
  • adds after_update/before_update callbacks
  • adds after_commit/after_rollback callbacks
  • reorganizes the way how callback method names are stored
  • now %mapping automatically guess is it should be sti or common mapping (should be used in places of %sti_mapping)
  • removed #attributes_hash
  • any time object is converted to UTC when is stored and to local when is retrieved from db

View

  • any time object is converted to local when is retrieved from db

Config

  • adds ::local_time_zone_name method to set application time zone
  • adds ::local_time_zone - returns local time zone object

Adapter

  • any time object passed as argument is converted from local time to UTC
  • postgres adapter now use INSERT with RETURNING
  • now several adapters could be required at the same time
  • all schema manipulation methods now in located in the SchemaProcessor

0.4.3 (2-01-2018)

  • All macro methods were rewritten to new 0.24.1 crystal syntax

Adapter

  • removed Jennifer::Adapter::TICKS_PER_MICROSECOND
  • fixes Jennifer::Adapter::Mysql#table_column_count bug

Model

  • add Primary32 and Primary64 shortcuts for primary key mapping (view mapping respects this as well)
  • add ::create! & ::create with splatted named tuple arguments
  • now relation retrieveness is updated for any superclass relations as well
  • a relation will be retrieved from db for only persisted record
  • move Jennifer::Mode::build method to %mapping macro
  • allow retrieving and building sti records using base class
  • fix #reload method for sti record
  • optimize building sti record from hash

QueryBuilder

  • fix Criteria#not
  • add Criteria#ilike

View

  • introduce View::Materialized superclass for materialized views
  • add COLUMNS_METADATA constant
  • add ::columns_tuple which returns COLUMNS_METADATA
  • remove ::children_classes
  • make after_initialize callback respect inheritance
  • add ::adapter

Exceptions

  • add AbstractMethod exception which presents expectation of overriding current method by parents (is useful when method can't be real abstract one)
  • add UnknownSTIType

0.4.2 (24-11-2017)

SqlGenerator

  • rename #trancate to #truncate

Migration

  • rename TableBuilder::DropIndex to TableBuilder::DropIndex
  • remove printing out redundant execution information during db drop and create
  • remove Migration::Base::TABLE_NAME constant
  • allow to pass QueryBuilder::Query as source to the CreateMaterializedView (postgres only)

Model

  • move Base#build method without arguments to Mapping module under the %mapping
  • added validates_presence_of validation macros
  • fixed callback invocation from parent classes
  • add allow_blank key to validates_inclusion, validates_exclusion, validates_format
  • add ValidationMessages module which includes methods generating validation error messages
  • add Primary32 and Primary64 shortcuts for Int32 and Int64 primary field declarations for model and view
  • allow use nil usions instead of null: true named tuple option

QueryBuilder

  • #count method is moved from Executables module to the Aggregations one
  • changed method signature of #find_in_batches
  • add #find_each - works same way as #find_in_batches but yields each record instead of array
  • add #ordered? method to Ordering module
  • switch Criteria#hash to use object_id as seed
  • add Query#eql?
  • add Query#clone and all related methods
  • add Query#except - creates clone except given clauses
  • make IModelQuery class as new superclass of ModelQuery(T); move all methods no depending on T to the new class

0.4.1 (20-10-2017)

Config

  • added port configuration
  • ::reset_config resets to default configurations
  • added validation for adapter and db
  • ::from_uri allows to load configuration from uri

Adapter

  • added #query_array method to request array of arrays of given type
  • added #with_table_lock which allows to lock table (mysql and postgres have different behaviors)

Query

  • added all and any statements
  • refactored logical operators - now they don't group themselves with "()"
  • added ExpressionBuilder#g (ExpressionBuilder#grouping) to group some condition
  • added XOR
  • moved all executable methods to Executables module
  • change behavior of #distinct - now it accepts no arguments and just prepend DISTINCT to common select query
  • added #find_in_batches - allows to search over requested collection required only determined amount of records per iteration
  • #find_records_by_sql - returns array of Record by given sql string
  • added :full_outer join type
  • added #lateral_join to make LATERAL JOIN (for now is supported only by PostgreSQL)
  • extracted all join methods to Joining module
  • extracted all ordering methods to Ordering module
  • added #reorder method allowing to reorder existing query

ModelQuery

  • added #find_by_sql similar to Query#find_records_by_sql

Model

  • added ::with_table_lock
  • added ::adapter
  • added ::import to perform one query import
  • fixed bug with reloading empty relations

Mapping

  • added inverse_of option to has_many and has_one relations to sets owner during relation loading

0.4.0 (30-09-2017)

Exception

  • BadQuery now allows to append query body to the main error text

Adapter

  • added #view_exists?(name)

QueryBuilder

  • now #eager_load behaves as old variant of #includes - via joining relations and adding them to the SELECT statement (breaking changes)

  • added #preload method which allows to load all listed relations after execution of main request

  • new behavior of #includes is same as #preload (breaking changes)

  • added Jennifer::QueryBuilder::QueryObject which designed to be as a abstract class for query objects for Model::Base scopes (will be renamed in futher releases)

  • all query related objects are clonable

  • now GROUP clause is placed right after the WHERE clause

  • aggregation methods is moved to Jennifer::QueryBuilder::Aggregations module which is included in the Query class

  • Query#select now accepts Criteria object, Symbol (which now will be transformed to corresponding Criteria), 'String' (which will be transformed to RawSql), string and symbol tuples, array of criterion and could raise a block with ExpressionBuilder as a current context (Array(Criteria) is expected to be returned)

  • Query#group got same behavior as Query#select

  • Query#order realize same idea as with Query#select but with hashes

  • added Criteria#alias method which allows to alias field in the SELECT clause

  • ExpressionBuilder#star creates "all" attribute; allows optional argument specifying table name

  • RawSql now has @use_brakets attribute presenting whether sql statement should be surrounded by brackets

  • Criteria#sql method now accepts use_brackets argument which is passed to RawSql

Migration

  • mysql got #varchar method for column definition
  • added invoking of TableBuilder::CreateMaterializedView in #create_materialized_view method
  • now Jennifer::TableBuilder::CreateMaterializedView accepts only String query
  • added #drop_materialized_view
  • added CreateIndex, DropIndex, CreateView, DropView classes and corresponding methods

Record

  • added attribute(name : String, type : T.class) method

Model

  • added ::context method which return expression builder for current model
  • added ::star method which returns "all" criteria
  • moved scope definition to Scoping module
  • now scopes accepts QueryBuilder::QueryObject class name as a 2nd argument
  • now object inserting into db use old variant with inserting and grepping last inserted id (because of bug with pg crystal driver)

View

  • added view support for both mysql and postgres - name of abstract class for inheritance Jennifer::View::Base
Github statistic:
  • 195
  • 33
  • 9
  • 8
  • about 7 hours ago

License:

MIT License

Links: