This document introduces Scala ActiveRecord, an ORM library for Scala that aims to provide an ActiveRecord-like experience. It summarizes the motivations for creating Scala ActiveRecord, which were to have a more usable database library that supports type-safety, conventions over configuration, and avoids repetition. It describes key features of Scala ActiveRecord like validations, associations, and callbacks. It also provides examples of basic CRUD operations and queries using Scala ActiveRecord's interface.
Akka and the Zen of Reactive System DesignLightbend
In order to be successful with asynchronous programming, when coming from synchronous execution models you need to change your mindset and look at things from a slightly different perspective. In order to use Akka at it's best, you will have to change the way you think about application design (loosen coupling in space and time between components), and re-think what you've maybe learned in the past.
In this talk we uncover a number of rules that serve as a guide in designing concurrent distributed applications, how those apply to Akka, and how they can help you in daily app development.
Aimed at developers through architects, Akka team happy hAkker, Konrad Malawski, bends your parameters with regards to application design and asynchronous execution models.
Akka and the Zen of Reactive System DesignLightbend
In order to be successful with asynchronous programming, when coming from synchronous execution models you need to change your mindset and look at things from a slightly different perspective. In order to use Akka at it's best, you will have to change the way you think about application design (loosen coupling in space and time between components), and re-think what you've maybe learned in the past.
In this talk we uncover a number of rules that serve as a guide in designing concurrent distributed applications, how those apply to Akka, and how they can help you in daily app development.
Aimed at developers through architects, Akka team happy hAkker, Konrad Malawski, bends your parameters with regards to application design and asynchronous execution models.
Got data? Let's make it searchable! This interactive presentation will demonstrate getting documents into Solr quickly, provide some tips in adjusting Solr's schema to match your needs better, and finally showcase your data in a flexible search user interface. We'll see how to rapidly leverage faceting, highlighting, spell checking, and debugging. Even after all that, there will be enough time left to outline the next steps in developing your search application and taking it to production.
Slides from my Lonestar Ruby Conf 2011 presentation.
*** Video of presentation: http://confreaks.com/videos/2531-lsrc2011-testing-javascript-with-jasmine ***
Agenda:
- Briefly cover why you should unit test
- Discuss what Jasmine is and isn't
- Show syntax with comparisons to RSpec
- Jasmine with:
- Vanilla JavaScript
- Jasmine with jQuery
- Jasmine with Ruby (not Rails)
- Jasmine with Rails
- Evergreen
- capybara-webkit
- Where does CoffeeScript, node.js, etc. fit in?
- Other helpful libraries/Wrap-up
Search application development can start the moment you download Solr. As you ingest your data, or a sample thereof, you can easily see the search results in a familiar search user interface. Want to facet on a field? Done. Want to full-text search on a field? Change some configuration, restart, reindex, and voila! Done right, the iterative process of development and discovery will help you better match users to the data they need and deliver a quality search experience.
This slide shows you how to use Akka cluster in Java.
Source Code: https://github.com/jiayun/akka_samples
If you want to use the links in slide, please download the pdf file.
Here are the slides that I gave for The Arizona Software Community meetup.
http://www.meetup.com/azsoftcom/events/222936544/
This was a gentle introduction to some of the features in EcmaScript 2015 and how and why you may use them.
Software development is riddled with explicit and implicit costs. Every decision you make has a cost attached to it. When you're writing code, you're making an investment, the size of which will for a long time define the costs of your future growth. Making right decision about these investments is very tricky and the cost of wrong decisions might be crippling for both business and teams that support it.
Extreme Programming and Test Driven Development in particular are practices that are aiming at supporting development effort by making it easier to introduce change. That said, sometimes those tools can become a problem of its own when applied in the wrong way or for the wrong context. Understanding software cost forces is a very important skill of successful teams and something that helps understand how to apply XP and TDD in different contexts.
Got data? Let's make it searchable! This interactive presentation will demonstrate getting documents into Solr quickly, provide some tips in adjusting Solr's schema to match your needs better, and finally showcase your data in a flexible search user interface. We'll see how to rapidly leverage faceting, highlighting, spell checking, and debugging. Even after all that, there will be enough time left to outline the next steps in developing your search application and taking it to production.
Slides from my Lonestar Ruby Conf 2011 presentation.
*** Video of presentation: http://confreaks.com/videos/2531-lsrc2011-testing-javascript-with-jasmine ***
Agenda:
- Briefly cover why you should unit test
- Discuss what Jasmine is and isn't
- Show syntax with comparisons to RSpec
- Jasmine with:
- Vanilla JavaScript
- Jasmine with jQuery
- Jasmine with Ruby (not Rails)
- Jasmine with Rails
- Evergreen
- capybara-webkit
- Where does CoffeeScript, node.js, etc. fit in?
- Other helpful libraries/Wrap-up
Search application development can start the moment you download Solr. As you ingest your data, or a sample thereof, you can easily see the search results in a familiar search user interface. Want to facet on a field? Done. Want to full-text search on a field? Change some configuration, restart, reindex, and voila! Done right, the iterative process of development and discovery will help you better match users to the data they need and deliver a quality search experience.
This slide shows you how to use Akka cluster in Java.
Source Code: https://github.com/jiayun/akka_samples
If you want to use the links in slide, please download the pdf file.
Here are the slides that I gave for The Arizona Software Community meetup.
http://www.meetup.com/azsoftcom/events/222936544/
This was a gentle introduction to some of the features in EcmaScript 2015 and how and why you may use them.
Software development is riddled with explicit and implicit costs. Every decision you make has a cost attached to it. When you're writing code, you're making an investment, the size of which will for a long time define the costs of your future growth. Making right decision about these investments is very tricky and the cost of wrong decisions might be crippling for both business and teams that support it.
Extreme Programming and Test Driven Development in particular are practices that are aiming at supporting development effort by making it easier to introduce change. That said, sometimes those tools can become a problem of its own when applied in the wrong way or for the wrong context. Understanding software cost forces is a very important skill of successful teams and something that helps understand how to apply XP and TDD in different contexts.
All matter, no matter how complex, can be broken down into molecules which can be broken down further into atomic elements. All web interfaces can be broken down down the same way. Atomic Design provides a methodology for building an effective design system. It consists of five distint stages: atoms, molecules, organisms, templates and pages.
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
Http4s, Doobie and Circe together form a nice platform for building web services. This presentations provides an introduction to using them to build your own service.
In this intro-level session on utilizing jQuery with SharePoint, the focus will be to empower users on how to satisfy some of the common UI changes clients request by writing clean and unobtrusive Javascript with the help of the jQuery library. We'll begin by diving into the different ways that jQuery can be hooked up to SharePoint. We'll talk about CDN versus local copies of the library, as well as linking jQuery via masterpages, custom actions, content editor web parts, and more.
We'll then spend time discussing css selectors, and some of the common patterns and jQuery methods you'll want to familiarize yourself with when targeting page-level elements. After that, the remainder of the presenation will be focused on walking through real-life scenarios of altering the UI with jQuery, such as adding interaction and animation to content query webparts, changing the behavior of links inside a page, and more. The code utilized in the presentation will be made available online after the Conference is completed.
Short (45 min) version of my 'Pragmatic Real-World Scala' talk. Discussing patterns and idioms discovered during 1.5 years of building a production system for finance; portfolio management and simulation.
5. Features Version 0.1
Squeryl wrapper
Type-safe (most part)
Rails ActiveRecord-like operability
CoC (Convention over Configuration)
DRY (Don't Repeat Yourself) principles.
Auto transaction control
“Type-safed ActiveRecord model for Scala”
6. Features Version 0.2
Validations
Associations
Testing support
Improving query performance
Scala 2.10 support
11. (1) Anorm
ORMではなく、Model層を提供しない設計思想のため、
どうしてもClassごとに同じようなメソッドを定義せざ
るを得なくなる
case class Person(id: Pk[Long], name: String)
object Person {
def create(person: Person): Unit = {
DB.withConnection { implicit connection =>
SQL("insert into person(name) values ({name})").on(
'name -> person.name).executeUpdate()
}
}
...
}
Not DRY...
12. (2) Slick (ScalaQuery)
Queryの使用感は良いが、テーブル定義がやや冗長。
Modelとマッピングする場合、その対応をテーブルごと
に明示的に記述する必要がある
case class Member(id: Int, name: String, email: Option[String])
object Members extends Table[Member]("MEMBERS") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("NAME")
def email = column[Option[String]]("EMAIL")
def * = id.? ~ name ~ email <> (Member, Member.unapply _)
}
Query interface is Good.
But, not DRY defining tables.
13. (3) Squeryl
ScalaのORMとしては最も良い出来
Queryに対してさらに条件を指定したQueryを作成すると
Sub-QueryなSQLが呼び出される
val query = from(table)(t => where(t.id.~ > 20) select(t))
from(query)(t => where(t.name like “%test%”) select(t))
Select * From
(Select * From table Where table.id > 20) q1
Where q1.name like “test”
Very nice ORM library.
Need to be aware of the SQL performance.
14. Improvements from Squeryl
Queryの合成結果が単なるSub Queryにならないように
Queryの条件をパフォーマンス劣化せず流用可能
val query = Table.where(_.id.~ > 20)
query.where(_.name like “%test%”).toList
Select * From table
Where
table.id > 20 and table.name like “test”
Generates more simple SQL statement.
16. Improvements from Squeryl
関連設定ルールをCoCで結び付けられるように
関連参照時のQueryがSubQueryにならないように
Eager loadingを実装
Simpler association definition rule.
17. Association definition (Squeryl)
object Schema extends Schema {
val foo = table[Foo]
val bar = table[Bar]
val fooToBar = oneToManyRelation(Foo, Bar).via(
(f, b) => f.barId === b.id
)
}
class Foo(var barId: Long) extends SomeEntity {
lazy val bar: ManyToOne[Bar] =
schema.fooToBar.right(this)
}
class Bar(var bar: String) extends SomeEntity {
lazy val foos: OneToMany[Foo] =
schema.fooToBar.left(this)
}
18. Association definition
(Scala ActiveRecord)
object Tables extends ActiveRecordTables {
val foo = table[Foo]
val bar = table[Bar]
}
class Foo(var barId: Long) extends ActiveRecord {
lazy val bar = belongsTo[Bar]
}
class Bar(var bar: String) extends ActiveRecord {
lazy val foos = hasMany[Foo]
}
20. Model implementation
case class Person(var name: String, var age: Int)
extends ActiveRecord
object Person
extends ActiveRecordCompanion[Person]
Schema definition
object Tables extends ActiveRecordTables {
val people = table[Person]
}
21. Create
val person = Person("person1", 25)
person.save
true
val person = Person("person1", 25).create
Person(“person1”, 25)
26. Single object finder
val client = Client.find(10)
Some(Client) or None
val john = Client.findBy("name", "john")
Some(Client("john")) or None
val john25 = Client.findBy(("name", "john"), ("age", 25))
Some(Client("john", 25)) or None
27. Multiple object finder
Clients.where(c =>
c.name === "john" and c.age.~ > 25
).toList
Clients.where(_.name === "john")
.where(_.age.~ > 25)
.toList
Select
clients.name, clients.age, clients.id
From
clients
Where
clients.name = “john” and clients.age > 25
28. Using `Iterable` methods
val client = Client.head
First Client or RecordNotFoundException
val client = Client.lastOption
Some(Last Client) or None
val (adults, children) = Client.partition(_.age >= 20)
Parts of clients
29. Ordering
* Simple order (ORDER BY client.name)
Client.orderBy(_.name)
* Set order (use for 'asc' or 'desc')
Client.orderBy(_.name asc)
* Ordering by multiple fields
Client.orderBy(_.name asc, _.age desc)
30. Limit and Offset
Client.limit(10)
Client.page(2, 5)
Existence of objects
Client.exists(_.name like "john%")
true or false
35. Annotation-based Validation
case class User(
@Required name: String,
@Length(max=20) profile: String,
@Range(min=0, max=150) age: Int
) extends ActiveRecord
object User extends
ActiveRecordCompanion[User]
36. Validation Sample
// it’s not save in the database
// because the object is not valid
val user = User("", “Profile”, 25).create
user.isValid
false
user.hasErrors
true
user.errors.messges
Seq("Name is required")
user.hasError("name")
true
37. More functional error handling...
User("John", “profile”, 20).saveEither match {
case Right(user) => println(user.name)
case Left(errors) => println(errors.messages)
}
"John"
User("", “profile”, 15).saveEither match {
case Right(user) => println(user.name)
case Left(errors) => println(errors.messages)
}
"Name is required"
42. One-to-Many
case class User(name: String) extends ActiveRecord {
val groupId: Option[Long] = None
lazy val group = belongsTo[Group]
}
case class Group(name: String) extends ActiveRecord {
lazy val users = hasMany[User]
}
43. One-to-Many
val user1 = User("user1").create
val user2 = User("user2").create
val group1 = Group("group1").create
group1.users << user1
group1.users.toList
List(User("user1"))
user1.group.getOrElse(Group(“group2”))
Group("group1")
44. Association is Queryable
group1.users.where(_.name like “user%”)
.orderBy(_.id desc)
.limit(5)
.toList
Select
users.name, users.id
From
users
Where
((users.group_id = 1) AND (users.name like “user%”))
Order By
users.id Desc
limit 5 offset 0
45. Many-to-Many (HABTM)
case class User(name: String) extends ActiveRecord {
lazy val groups = hasAndBelongsToMany[Group]
}
case class Group(name: String) extends ActiveRecord {
lazy val users = hasAndBelongsToMany[User]
}
46. Many-to-Many (HABTM)
val user1 = User("user1").create
val user2 = User("user2").create
val group1 = Group("group1").create
val group2 = Group("group2").create
user1.groups := List(group1, group2)
user1.groups.toList
List(Group(“group1”), Group(“group2”))
group1.users.toList
List(User(“user1”))
47. Many-to-Many (hasManyThrough)
* Intermediate table's model
case class Membership(
userId: Long,
projectId: Long,
isAdmin: Boolean = false
) extends ActiveRecord
{
lazy val user = belongsTo[User]
lazy val group = belongsTo[Group]
}
48. Many-to-Many (hasManyThrough)
case class User(name: String) extends ActiveRecord {
lazy val memberships = hasMany[Membership]
lazy val groups =
hasManyThrough[Group, Membership](memberships)
}
case class Group(name: String) extends ActiveRecord {
lazy val memberships = hasMany[Membership]
lazy val users =
hasManyThrough[User, Membership](memberships)
}
49. Conditions option
case class Group(name: String) extends ActiveRecord {
lazy val adminUsers =
hasMany[User](conditions = Map("isAdmin" -> true))
}
group.adminUsers << user
user.isAdmin == true
ForeignKey option
case class Comment(name: String) extends ActiveRecord {
val authorId: Long
lazy val author =
belongsTo[User](foreignKey = “authorId”)
}
50. Joining tables
Client.joins[Order](
(client, order) => client.id === order.clientId
).where(
(client, order) => client.age.~ < 20 and order.price.~ > 1000
).select(
(client, order) => (client.name, client.age, order.price)
).toList
Select
clients.name, clients.age, orders.price
From
clients inner join orders on (clients.id = orders.client_id)
Where
((clients.age < 20) and (groups.price > 1000))
51. Eager loading associations
Solution to N + 1 queries problem
Order.includes(_.client).limit(10).map {
order => order.client.name
}.mkString(“n”)
Select orders.price, orders.id From orders limit 10 offset 0;
Select
clients.name, clients.age, clients.id
From
clients inner join orders on (clients.id = orders.client_id)
Where
(orders.id in (1,2,3,4,5,6,7,8,9,10))
53. Future prospects
Compile time validation (using macro)
Serialization support
Web framework support
(Offers view helpers for Play 2.x and Scalatra)
STI, Polymorphic Association
54. Compile time validation
(using macro)
型安全性が確保できていない部分について
Scala macro を利用した型安全化
ActiveRecord#findBy(key: String, value: Any)
Association( fe
conditions: Map[String, Any], e- sa
foreignKey: String ttyp
) No
Type-safe binding configuration
55. Serialization support
パーサを個別に定義することなく、モデルを
定義するだけで済むように
JSON
Bind
Form Model XML
View
helper
Validation MessagePack
View
56. Web framework support
CRUD controller
Form helper
scala-activerecord-play2
scala-activerecord-scalatra
Code generator Controller, Model, View
sbt generate scaffold Person name:string:required age:int
scala-activerecord-play2-sbt-plugin
scala-activerecord-scalatra-sbt-plugin etc..