onyx-sql

DB-agnostic SQL ORM with beautiful DSL and type-safe Query builder orm sql sql-orm query-builder crystal-db onyxframework
0.4.1 released
onyxframework/sql
90 6 24
Onyx Framework

Core

Built with Crystal Build status Docs Releases Awesome vladfaust.com

Core is an expressive modular ORM for Crystal featuring:

  • ⚡️ Efficiency based on Crystal performance
  • Expressiveness with powerful DSL and lesser code
  • 💼 Safety with strictly typed attributes

About

Core does not follow Active Record pattern, it's more like a data-mapping solution. There is a concept of Repository, which is basically a gateway to the database. For example:

repo = Core::Repository.new(db)
users = repo.query(User, "SELECT * FROM users WHERE id > 42")
users.class # => Array(User)

Core also has a plently of features, including:

  • Expressive Query builder, either standalone or module, allowing to use constructions like Post.join(:author).where(author: user), which turns into a plain SQL
  • References preloader (the example above would return a Post which has #author = <User @id=42> attribute)
  • Validations module allowing to perform both inline and custom validations (user.valid? # => true)

However, Core is designed to be minimal, so it doesn't perform task you may got used to, for example, it doesn't do database migrations itself. You may use migrate instead.

Installation

Add this to your application's shard.yml:

dependencies:
  core:
    github: vladfaust/core
    version: ~> 0.4.1

This shard follows Semantic Versioning v2.0.0, so check releases and change the version accordingly.

Basic example

Assuming following database schema:

CREATE TABLE users(
  id          SERIAL        PRIMARY KEY,
  name        VARCHAR(100)  NOT NULL,
  created_at  TIMESTAMPTZ   NOT NULL  DEFAULT NOW()
);

CREATE TABLE posts(
  id          SERIAL      PRIMARY KEY,
  author_id   INT         NOT NULL  REFERENCES users (id),
  content     TEXT        NOT NULL,
  created_at  TIMESTAMPTZ NOT NULL  DEFAULT NOW(),
  updated_at  TIMESTAMPTZ
);
require "core"
require "pg" # Or maybe another driver

class User
  include Core::Schema
  include Core::Query
  include Core::Validations

  schema :users do
    primary_key :id
    reference :posts, Array(Post), foreign_key: :author_id

    field :name, String, validate: {size: (3..100)}
    field :created_at, Time, db_default: true # Means that DB is handling the default value
  end
end

class Post
  include Core::Schema
  include Core::Query
  include Core::Validations

  schema :posts do
    primary_key :id
    reference :author, User, key: :author_id

    field :content, String
    field :created_at, Time, db_default: true
    field :updated_at, Time?
  end
end

db = DB.open(ENV["DATABASE_URL"])
query_logger = Core::Logger::IO.new(STDOUT)
repo = Core::Repository.new(db, query_logger)

user = User.new(name: "Vl")
user.valid? # => false
user.errors # => [{:name => "must have size in range of 3..100"}]
user.name = "Vlad"
user = repo.insert(user)

post = repo.insert(Post.new(author: user, content: "What a beauteful day!")) # Oops

post.content = "What a beautiful day!"
repo.update(post)

posts = repo.query(Post.where(author: user).join(:author))
puts posts.first.inspect
# => <Post @author=<User @name="Vlad"> @content="What a beautiful day!">

Testing

  1. Apply migration from ./spec/migration.sql
  2. Run env DATABASE_URL=your_database_url crystal spec

Contributing

  1. Fork it ( https://github.com/vladfaust/core/fork )
  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

Contributors

onyx-sql:
  github: onyxframework/sql
  version: ~> 0.4.1
License MIT
Crystal 0.26.0

Authors

Dependencies 2

  • db ~> 0.5.0
    {'github' => 'crystal-lang/crystal-db', 'version' => '~> 0.5.0'}
  • time_format ~> 0.1.0
    {'github' => 'vladfaust/time_format.cr', 'version' => '~> 0.1.0'}

Development Dependencies 1

  • pg ~> 0.15.0
    {'github' => 'will/crystal-pg', 'version' => '~> 0.15.0'}

Dependents 3

Last synced .
search fire star recently