Maiha's private ORM for Crystal
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
spec
src
.editorconfig
.gitignore
.travis.yml
Dockerfile
LICENSE
Makefile
README.md
docker-compose.yml
shard.yml

README.md

pon.cr Build Status

Maiha's private ORM for Crystal.

  • crystal: 0.27.0

Usage

require "pon"
require "pon/adapter/mysql"  # "mysql", "pg", "sqlite"

# Enum support!
enum Code
  OK  = 200
  ERR = 500
end

# Model definition
class Job < Pon::Model
  adapter mysql              # "mysql", "pg", "sqlite"
  field   name : String
  field   time : Time
  field   code : Code = Code::OK  # default value
end

Pon::Adapter::Mysql.setting.url = "mysql://root@127.0.0.1:3306/test"

# Create table
Job.migrate! # drop and create the table
Job.count                 # => 0

# CRUD
job = Job.new(name: "foo")
job.name                  # => "foo"
job.time?                 # => nil
job.time                  # raises Pon::ValueNotFound
job.code                  # => Code::OK
job.save                  # => true
Job.find(job.id).code.ok? # => true
Job.create!(name: "bar", code: Code::ERR)

# Finder
Job.all.size                      # => 2
Job.all(where: "code = 200").size # => 1
Job.all(["code"]).map(&.name?)    # => [nil, nil]

# And more useful features
Job.pluck(["name"]) # => [["foo"], ["bar"]]
Job.count_by_code   # => {Code::OK => 1, Code::ERR => 1}

API : Adapter

  def exec(sql) : Nil
  def lastval : Int64
  def scalar(*args)
  def reset! : Nil

  # CRUD
  def insert(fields, params)
  def all(fields : Array(String), types, condition = nil, **opts)
  def one?(id, fields : Array(String), as types : Tuple)
  def count : Int32
  def delete(key) : Bool
  def delete : Nil
  def truncate : Nil

  # ODBC
  def databases : Array(String)
  def tables : Array(String)

  # Experimental
  def transaction(&block) : Nil # only sqlite and pg

API : Model

class Pon::Model
  # Databases
  def self.adapter : Adapter(A)
  def self.migrator : Migrator
  def self.migrate! : Nil

  # Core
  def self.table_name : String
  def new_record? : Bool
  def to_h : Hash(String, ALL_TYPES)

  # CRUD
  def self.create! : M
  def self.create : M
  def self.count : Int32
  def self.all : Array(M)
  def self.all(query_string : String) : Array(M)
  def self.where(condition : String) : Array(M)
  def self.first : M
  def self.first? : M?
  def save : Bool
  def save! : Bool
  def self.delete_all
  def delete

  # Field "foo"
  def foo : T
  def foo? : T?
  def [](key) : T
  def []?(key) : T?
  def []=(key, val)

  # Aggregations
  def self.count_by_xxx : Hash(Type, Int64)

  # Misc
  def self.pluck(fields : Array(String))

API : Module

Pon.logger=(v : Logger)      # logger
Pon.query_logging=(v : Bool) # writes queries into the logger or not

Roadmap

  • Adapter Core
    • connect lazily
    • share same connection between adapters
    • exec plain sql
    • exec prepared statement
    • all
    • count
    • scalar
    • quote
    • escape
    • migrator
  • Adapter Drivers
    • reset connections
    • RDB
      • mysql
      • pg
      • sqlite
    • KVS
      • redis
  • Core
    • pluralize table names
    • special types (Enum)
    • custom type
    • multibytes
    • record status
    • inspect class and records
    • callbacks
    • validations
    • natural keys
    • default values
  • CRUD
    • create
    • delete, delete_all
    • find
    • save
  • Finder
    • all, count, first
    • pluck (with casting)
    • field aliases
  • Aggregations
    • count_by_xxx
  • Relations
    • belongs_to
    • has_many
    • has_many through
  • Misc
    • bulk insert
    • upsert

Installation

Add this to your application's shard.yml:

dependencies:
  pon:
    github: maiha/pon.cr
    version: 0.4.2

  # one of following adapter
  mysql:
    github: crystal-lang/crystal-mysql
    version: ~> 0.4.0
  sqlite3:
    github: crystal-lang/crystal-sqlite3
    version: ~> 0.9.0
  pg:
    github: will/crystal-pg
    version: ~> 0.14.1

Development

$ make spec

Contributing

  1. Fork it ( https://github.com/maiha/pon.cr/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

  • maiha maiha - creator, maintainer

Thanks / Inspiration