Skip to content

Commit 37fc33c

Browse files
committed
feat: rename to Atom::Model
BREAKING CHANGE: this repository is now the official SQL ORM of @atomframework!
1 parent a7bac0c commit 37fc33c

76 files changed

Lines changed: 388 additions & 373 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,57 @@
11
> ⚠️ Master branch requires Crystal master to compile. See [installation instructions for Crystal](https://crystal-lang.org/docs/installation/from_source_repository.html).
22
3-
# ![Core](https://user-images.githubusercontent.com/7955682/40578252-6f1929b2-6119-11e8-9348-81505cec939f.png)
3+
# Atom::Model
44

55
[![Built with Crystal](https://img.shields.io/badge/built%20with-crystal-000000.svg?style=flat-square)](https://crystal-lang.org/)
6-
[![Build status](https://img.shields.io/travis/vladfaust/core/master.svg?style=flat-square)](https://travis-ci.org/vladfaust/core)
7-
[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg?style=flat-square)](https://github.vladfaust.com/core)
8-
[![Releases](https://img.shields.io/github/release/vladfaust/core.svg?style=flat-square)](https://github.com/vladfaust/core/releases)
9-
[![Gitter Chat](https://img.shields.io/badge/style-chat-ed1965.svg?longCache=true&style=flat-square&label=&logo=gitter-white&colorA=555)](https://gitter.im/core-orm/Lobby)
6+
[![Build status](https://img.shields.io/travis/atomframework/model/master.svg?style=flat-square)](https://travis-ci.org/atomframework/model)
7+
[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg?style=flat-square)](http://api.model.atomframework.org)
8+
[![Releases](https://img.shields.io/github/release/atomframework/model.svg?style=flat-square)](https://github.com/atomframework/model/releases)
109
[![Awesome](https://github.com/vladfaust/awesome/blob/badge-flat-alternative/media/badge-flat-alternative.svg)](https://github.com/veelenga/awesome-crystal)
11-
[![vladfaust.com](https://img.shields.io/badge/style-.com-lightgrey.svg?longCache=true&style=flat-square&label=vladfaust&colorB=0a83d8)](https://vladfaust.com)
12-
[![Patrons count](https://img.shields.io/badge/dynamic/json.svg?label=patrons&url=https://www.patreon.com/api/user/11296360&query=$.included[0].attributes.patron_count&style=flat-square&colorB=red&maxAge=86400)](https://www.patreon.com/vladfaust)
1310

14-
Type-safe and expressive SQL ORM for [Crystal](https://crystal-lang.org).
11+
The official SQL ORM for [Atom Framework](https://github.com/atomframework/atom).
1512

16-
[![Become Patron](https://vladfaust.com/img/patreon-small.svg)](https://www.patreon.com/vladfaust)
17-
18-
## Projects using Core
13+
## Projects using Atom::Model
1914

2015
* [Crystal Jobs](https://crystaljobs.org)
2116
* [Crystal World](https://github.com/vladfaust/crystalworld)
2217
* *add yours!*
2318

2419
## About
2520

26-
Core is a [crystal-db](https://github.com/crystal-lang/crystal-db) ORM which 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:
21+
Atom::Model is a [crystal-db](https://github.com/crystal-lang/crystal-db) ORM which 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:
2722

2823
```crystal
29-
repo = Core::Repository.new(db)
24+
repo = Atom::Repository.new(db)
3025
users = repo.query(User.where(id: 42)).first
3126
users.class # => User
3227
```
3328

34-
Core also has a plently of features, including:
29+
Atom::Model also has a plently of features, including:
3530

3631
- Expressive and **type-safe** Query builder, allowing to use constructions like `Post.join(:author).where(author: user)`, which turns into a plain SQL
3732
- References preloader (the example above would return a `Post` which has `#author = <User @id=42>` attribute set)
3833
- Beautiful schema definition syntax
3934

40-
However, Core is designed to be minimal, so it doesn't perform tasks you may got used to, for example, it doesn't do database migrations itself. You may use [migrate](https://github.com/vladfaust/migrate.cr) instead. Also its Query builder is not intended to fully replace SQL but instead to help a developer to write less and safer code.
35+
However, Atom::Model is designed to be minimal, so it doesn't perform tasks you may got used to, for example, it doesn't do database migrations itself. You may use [migrate](https://github.com/vladfaust/migrate.cr) instead. Also its Query builder is not intended to fully replace SQL but instead to help a developer to write less and safer code.
4136

42-
Also note that although Core code is designed to be abstract sutiable for any [crystal-db](https://github.com/crystal-lang/crystal-db) driver, it currently works with PostgreSQL only. But it's fairly easy to implement other drivers like MySQL or SQLite (see `/src/core/ext/pg` and `/src/core/repository.cr`).
37+
Also note that although Atom::Model code is designed to be abstract sutiable for any [crystal-db](https://github.com/crystal-lang/crystal-db) driver, it currently works with PostgreSQL only. But it's fairly easy to implement other drivers like MySQL or SQLite (see `/src/model/ext/pg` and `/src/model/repository.cr`).
4338

4439
## Installation
4540

4641
Add this to your application's `shard.yml`:
4742

4843
```yaml
4944
dependencies:
50-
core:
51-
github: vladfaust/core
45+
atom-model:
46+
github: atomframework/model
5247
version: ~> 0.5.0
5348
```
5449
55-
This shard follows [Semantic Versioning v2.0.0](http://semver.org/), so check [releases](https://github.com/vladfaust/core/releases) and change the `version` accordingly.
50+
This shard follows [Semantic Versioning v2.0.0](http://semver.org/), so check [releases](https://github.com/atomframework/model/releases) and change the `version` accordingly.
51+
52+
## Using
5653

57-
## Basic example
54+
### Basic example
5855

5956
Assuming following database migration:
6057

@@ -79,10 +76,10 @@ Crystal code:
7976

8077
```crystal
8178
require "pg"
82-
require "core"
79+
require "atom-model"
8380
8481
class User
85-
include Core::Schema
82+
include Atom::Model
8683
8784
schema users do
8885
pkey uuid : UUID # UUIDs are supported out of the box
@@ -96,7 +93,7 @@ class User
9693
end
9794
9895
class Post
99-
include Core::Schema
96+
include Atom::Model
10097
10198
schema posts do
10299
pkey id : Int32
@@ -109,8 +106,8 @@ class Post
109106
end
110107
end
111108
112-
query_logger = Core::Logger::IO.new(STDOUT)
113-
repo = Core::Repository.new(DB.open(ENV["DATABASE_URL"]), query_logger)
109+
logger = Atom::Repository::Logger::IO.new(STDOUT)
110+
repo = Atom::Repository.new(DB.open(ENV["DATABASE_URL"]), logger)
114111
115112
# Most of the query builder methods (e.g. insert) are type-safe
116113
user = repo.query(User.insert(name: "Vlad")).first
@@ -139,16 +136,39 @@ puts posts.first.inspect
139136
# => <Post @id=42 @author=<User @name="Vlad" @uuid="..."> @content="What a beautiful day!">
140137
```
141138

139+
### With [Atom](https://github.com/atomframework/atom)
140+
141+
Define your models as above, but with `Model` as an alias of `Atom::Model` and [`Validations`](https://github.com/vladfaust/validations.cr) included by default. You also don't need to initialize repository explicitly when using Atom:
142+
143+
```crystal
144+
require "atom"
145+
146+
Atom.model(PG)
147+
148+
class User
149+
include Model
150+
151+
schema do
152+
type name : String
153+
end
154+
155+
validate name, size: (3..50)
156+
end
157+
158+
users = query(User.all) # Top-level `query`, `exec` and `scalar` methods
159+
User.new("Jo").valid? # Validations
160+
```
161+
142162
## Testing
143163

144164
1. Run generic specs with `crystal spec`
145165
2. Apply migrations from `./db_spec/*/migration.sql`
146-
3. Run DB-specific specs with `env POSTGRESQL_URL=postgres://postgres:postgres@localhost:5432/core crystal spec db_spec`
166+
3. Run DB-specific specs with `env POSTGRESQL_URL=postgres://postgres:postgres@localhost:5432/model crystal spec db_spec`
147167
4. Optionally run benchmarks with `crystal bench.cr --release`
148168

149169
## Contributing
150170

151-
1. Fork it ( https://github.com/vladfaust/core/fork )
171+
1. Fork it ( https://github.com/atomframework/model/fork )
152172
2. Create your feature branch (git checkout -b my-new-feature)
153173
3. Commit your changes (git commit -am 'Add some feature')
154174
4. Push to the branch (git push origin my-new-feature)

bench/logger_bench.cr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require "./bench_helper"
22

3-
puts "\nRunning Core::Logger benchmarks...\n".colorize(COLORS["header"])
3+
puts "\nRunning Atom::Repository::Logger benchmarks...\n".colorize(COLORS["header"])
44

55
def devnull
66
File.open(File::DEVNULL, mode: "w")
@@ -10,25 +10,25 @@ logger = Logger.new(devnull, Logger::DEBUG)
1010

1111
elapsed = Time.measure do
1212
Benchmark.ips do |x|
13-
io = Core::Logger::IO.new(devnull)
13+
io = Atom::Repository::Logger::IO.new(devnull)
1414

1515
x.report "io w/ colors" do
1616
io.wrap("foo") { nil }
1717
end
1818

19-
io = Core::Logger::IO.new(devnull, false)
19+
io = Atom::Repository::Logger::IO.new(devnull, false)
2020

2121
x.report "io w/o colors" do
2222
io.wrap("foo") { nil }
2323
end
2424

25-
std_logger = Core::Logger::Standard.new(logger, Logger::Severity::INFO)
25+
std_logger = Atom::Repository::Logger::Standard.new(logger, Logger::Severity::INFO)
2626

2727
x.report "logger w/ colors" do
2828
std_logger.wrap("foo") { nil }
2929
end
3030

31-
std_logger = Core::Logger::Standard.new(logger, Logger::Severity::INFO, false)
31+
std_logger = Atom::Repository::Logger::Standard.new(logger, Logger::Severity::INFO, false)
3232

3333
x.report "logger w/o colors" do
3434
std_logger.wrap("foo") { nil }

db_spec/repository_spec.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ enum Database
55
end
66

77
def repo(database : Database)
8-
Core::Repository.new(DB.open(ENV["#{database.to_s.upcase}_URL"]), Core::Logger::IO.new(STDOUT))
8+
Atom::Repository.new(DB.open(ENV["#{database.to_s.upcase}_URL"]), Atom::Repository::Logger::IO.new(STDOUT))
99
end

db_spec/spec_helper.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
require "spec"
2+
require "../src/atom-model"
23
require "../spec/models"

shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: core
1+
name: atom-model
22
version: 0.5.0
33

44
authors:

spec/logger/dummy_spec.cr

Lines changed: 0 additions & 9 deletions
This file was deleted.

spec/logger/io_spec.cr

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require "../models"
22

3-
describe "Schema changes" do
3+
describe "Atom::Model schema changes" do
44
user = User.new(name: "John")
55

66
it "has initially empty changes" do
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,85 @@
11
require "../query/**"
22

3-
describe "Schema query shortcuts" do
3+
describe "Atom::Model schema query shortcuts" do
44
describe ".group_by" do
55
it do
6-
User.group_by("foo", "bar").should eq Core::Query(User).new.group_by("foo", "bar")
6+
User.group_by("foo", "bar").should eq Atom::Query(User).new.group_by("foo", "bar")
77
end
88
end
99

1010
describe ".having" do
1111
it do
12-
User.having("foo").having("bar = ?", 42).should eq Core::Query(User).new.having("foo").having("bar = ?", 42)
12+
User.having("foo").having("bar = ?", 42).should eq Atom::Query(User).new.having("foo").having("bar = ?", 42)
1313
end
1414
end
1515

1616
describe ".insert" do
1717
it do
18-
User.insert(name: "John").should eq Core::Query(User).new.insert(name: "John")
18+
User.insert(name: "John").should eq Atom::Query(User).new.insert(name: "John")
1919
end
2020
end
2121

2222
describe ".limit" do
2323
it do
24-
User.limit(1).should eq Core::Query(User).new.limit(1)
24+
User.limit(1).should eq Atom::Query(User).new.limit(1)
2525
end
2626
end
2727

2828
describe ".offset" do
2929
it do
30-
User.offset(1).should eq Core::Query(User).new.offset(1)
30+
User.offset(1).should eq Atom::Query(User).new.offset(1)
3131
end
3232
end
3333

3434
describe ".set" do
3535
it do
36-
User.set(active: true).should eq Core::Query(User).new.set(active: true)
36+
User.set(active: true).should eq Atom::Query(User).new.set(active: true)
3737
end
3838
end
3939

4040
describe ".where" do
4141
it do
42-
User.where(active: true).should eq Core::Query(User).new.where(active: true)
42+
User.where(active: true).should eq Atom::Query(User).new.where(active: true)
4343
end
4444
end
4545

4646
{% for m in %w(update delete all one first last) %}
4747
describe {{m}} do
4848
it do
49-
User.{{m.id}}.should eq Core::Query(User).new.{{m.id}}
49+
User.{{m.id}}.should eq Atom::Query(User).new.{{m.id}}
5050
end
5151
end
5252
{% end %}
5353

5454
describe ".join" do
5555
context "with table" do
5656
it do
57-
Post.join("users", "author.id = posts.author_id", as: "author").should eq Core::Query(Post).new.join("users", "author.id = posts.author_id", as: "author")
57+
Post.join("users", "author.id = posts.author_id", as: "author").should eq Atom::Query(Post).new.join("users", "author.id = posts.author_id", as: "author")
5858
end
5959
end
6060

6161
context "with reference" do
6262
it do
63-
Post.join(:author, select: {'*'}).should eq Core::Query(Post).new.join(:author, select: {'*'})
63+
Post.join(:author, select: {'*'}).should eq Atom::Query(Post).new.join(:author, select: {'*'})
6464
end
6565
end
6666
end
6767

6868
describe ".order_by" do
6969
it do
70-
User.order_by(:uuid, :asc).order_by("foo").should eq Core::Query(User).new.order_by(:uuid, :asc).order_by("foo")
70+
User.order_by(:uuid, :asc).order_by("foo").should eq Atom::Query(User).new.order_by(:uuid, :asc).order_by("foo")
7171
end
7272
end
7373

7474
describe ".returning" do
7575
it do
76-
User.returning(:name).returning('*').should eq Core::Query(User).new.returning(:name).returning('*')
76+
User.returning(:name).returning('*').should eq Atom::Query(User).new.returning(:name).returning('*')
7777
end
7878
end
7979

8080
describe ".select" do
8181
it do
82-
User.select(:name).select('*').should eq Core::Query(User).new.select(:name).select('*')
82+
User.select(:name).select('*').should eq Atom::Query(User).new.select(:name).select('*')
8383
end
8484
end
8585

spec/models.cr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
require "../src/core"
1+
require "./spec_helper"
22

33
class User
4-
include Core::Schema
4+
include Atom::Model
55

66
enum Role
77
Writer
@@ -43,7 +43,7 @@ class User
4343
end
4444

4545
class Tag
46-
include Core::Schema
46+
include Atom::Model
4747

4848
schema tags do
4949
pkey id : Int32
@@ -53,7 +53,7 @@ class Tag
5353
end
5454

5555
class Post
56-
include Core::Schema
56+
include Atom::Model
5757

5858
schema posts do
5959
pkey id : Int32

0 commit comments

Comments
 (0)