Rasti::DB

Gem Version Build Status Coverage Status Code Climate Dependency Status

Database collections and relations

Installation

Add this line to your application's Gemfile:

gem 'rasti-db'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rasti-db

Usage

Database connection

DB = Sequel.connect ...

Database schema

DB.create_table :users do
  primary_key :id
  String :name, null: false, unique: true
end

DB.create_table :posts do
  primary_key :id
  String :title, null: false, unique: true
  String :body, null: false
  foreign_key :user_id, :users, null: false, index: true
end

DB.create_table :comments do
  primary_key :id
  String :text, null: false
  foreign_key :user_id, :users, null: false, index: true
  foreign_key :post_id, :posts, null: false, index: true
end

DB.create_table :categories do
  primary_key :id
  String :name, null: false, unique: true
end

DB.create_table :categories_posts do
  foreign_key :category_id, :categories, null: false, index: true
  foreign_key :post_id, :posts, null: false, index: true
  primary_key [:category_id, :post_id]
end

Models

User     = Rasti::DB::Model[:id, :name, :posts, :comments]
Post     = Rasti::DB::Model[:id, :title, :body, :user_id, :user, :comments, :categories]
Comment  = Rasti::DB::Model[:id, :text, :user_id, :user, :post_id, :post]
Category = Rasti::DB::Model[:id, :name, :posts]

Collections

class Users < Rasti::DB::Collection
  one_to_many :posts
  one_to_many :comments
end

class Posts < Rasti::DB::Collection
  many_to_one :user
  many_to_many :categories
  one_to_many :comments

  query :created_by do |user_id| 
    where user_id: user_id
  end

  query :entitled, -> (title) { where title: title }

  query :commented_by do |user_id|
    chainable do
      dataset.join(with_schema(:comments), post_id: :id)
             .where(with_schema(:comments, :user_id) => user_id)
             .select_all(with_schema(:posts))
             .distinct
    end
  end
end

class Comments < Rasti::DB::Collection
  many_to_one :user
  many_to_one :post
end

class Categories < Rasti::DB::Collection
  many_to_many :posts
end

users      = Users.new DB
posts      = Posts.new DB
comments   = Comments.new DB
categories = Categories.new DB

Persistence

DB.transaction do
  id = users.insert name: 'User 1'
  users.update id, name: 'User updated'
  users.delete id

  users.bulk_insert [{name: 'User 1'}, {name: 'User 2'}]
  users.bulk_update(name: 'User updated') { where id: [1,2] }
  users.bulk_delete { where id: [1,2] }
end

Queries

posts.all # => [Post, ...]
posts.first # => Post
posts.count # => 1
posts.where(id: [1,2]) # => [Post, ...]
posts.where{id > 1}.limit(10).offset(20) } # => [Post, ...]
posts.graph(:user, :categories, 'comments.user') # => [Post(User, [Categories, ...], [Comments(User)]), ...]
posts.created_by(1) # => [Post, ...]
posts.created_by(1).entitled('...').commented_by(2) # => [Post, ...]
posts.where(id: [1,2]).raw # => [{id:1, ...}, {id:2, ...}]
posts.where(id: [1,2]).primary_keys # => [1,2]
posts.where(id: [1,2]).pluck(:id) # => [1,2]
posts.where(id: [1,2]).pluck(:id, :title) # => [[1, ...], [2, ...]]

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/gabynaiman/rasti-db.

License

The gem is available as open source under the terms of the MIT License.