Skip to content

Commit 2a7f48c

Browse files
committed
Updated support
1 parent e3801df commit 2a7f48c

Some content is hidden

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

44 files changed

+3113
-0
lines changed

_old_posts/0.9.6.textile

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: default
3+
title: Migrating to 0.9.6
4+
headtitle: Migrating to 0.9.6
5+
---
6+
7+
h2. The companion object of trait org.squeryl.PrimitiveTypeMode is deprecated
8+
9+
From 0.9.6 onwards, the new usage pattern for importin Squeryls's DSL into an application is
10+
to define an entrypoint object and import it whereever the application uses the DSL.
11+
This object is also where KeyedEntities and custom types are defined.
12+
13+
*Note:* the trait org.squeryl.PrimitiveTypeMode is *not* deprecated, only it's companion object
14+
15+
h4. In the next example, we defined an object SquerylEntrypointForMyApp that will be imported in an application wherever the DSL is used.
16+
17+
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
18+
19+
import org.squeryl._
20+
import org.squeryl.dsl._
21+
import org.joda.time._
22+
import java.sql.Timestamp
23+
import java.sql.ResultSet
24+
25+
object SquerylEntrypointForMyApp extends PrimitiveTypeMode {
26+
27+
// optionally define keyed entities :
28+
implicit object courseKED extends KeyedEntityDef[Course,Int] {
29+
def getId(a:Course) = a.id
30+
def isPersisted(a:Course) = a.id > 0
31+
def idPropertyName = "id"
32+
override def optimisticCounterPropertyName = Some("occVersionNumber")
33+
}
34+
35+
// optionally define custom types :
36+
37+
implicit val jodaTimeTEF = new NonPrimitiveJdbcMapper[Timestamp, DateTime, TTimestamp](timestampTEF, this) {
38+
39+
/**
40+
* Here we implement functions fo convert to and from the native JDBC type
41+
*/
42+
43+
def convertFromJdbc(t: Timestamp) = new DateTime(t)
44+
def convertToJdbc(t: DateTime) = new Timestamp(t.getMillis())
45+
}
46+
47+
/**
48+
* We define this one here to allow working with Option of our new type, this allso
49+
* allows the 'nvl' function to work
50+
*/
51+
implicit val optionJodaTimeTEF =
52+
new TypedExpressionFactory[Option[DateTime], TOptionTimestamp]
53+
with DeOptionizer[Timestamp, DateTime, TTimestamp, Option[DateTime], TOptionTimestamp] {
54+
55+
val deOptionizer = jodaTimeTEF
56+
}
57+
58+
/**
59+
* the following are necessary for the AST lifting
60+
*/
61+
implicit def jodaTimeToTE(s: DateTime) = jodaTimeTEF.create(s)
62+
63+
implicit def optionJodaTimeToTE(s: Option[DateTime]) = optionJodaTimeTEF.create(s)
64+
}
65+
66+
// elsewhere in the application :
67+
68+
import SquerylEntrypointForMyApp._
69+
70+
]]></script>
71+
72+
73+
*Warning*: Although deprecared, the org.squeryl.PrimitiveTypeMode companion object can still be used for backward compatibility.
74+
If it is used, it *cannot* be used in a same application with other instance of the
75+
org.squeryl.PrimitiveTypeMode trait.
76+
77+
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
78+
79+
// WRONG, do not do this :
80+
81+
object SquerylEntrypointForMyApp extends org.squeryl.PrimitiveTypeMode
82+
83+
import SquerylEntrypointForMyApp._
84+
85+
// elsewhere in the application
86+
87+
import org.squeryl.PrimitiveTypeMode._
88+
}
89+
90+
]]></script>

_old_posts/about.textile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
layout: default
3+
title: Community
4+
headtitle: Community -
5+
---
6+
7+
8+
h2.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
layout: manual
3+
title: Evaluating arbitrary expressions on the database side
4+
---
5+
6+
h2. The <u>&</u> function
7+
8+
Squeryl's select clause will take any closure in parameter and evaluate it on the client side (client side as opposed to database side). Sometimes the expressions needs to be evaluated on the database side, this is what the *&* function does :
9+
10+
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
11+
12+
// the * is done on the client side :
13+
14+
from(artists)(a =>
15+
select(a.id * 1000)
16+
)
17+
18+
// in this case it is computed by the database :
19+
20+
from(artists)(a =>
21+
select(&(a.id * 1000))
22+
)
23+
]]></script>
24+
25+
* Note that the return type are equivalent in both cases, i.e. both queries resolve to *Query[Float]*
26+
27+
28+
A select can have more than one invocation of & :
29+
30+
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
31+
32+
val q: Query[Tuple2[Double, String]] =
33+
from(artists)(a =>
34+
select((&(a.id * 1000), &(a.firstName || a.lastName)))
35+
)
36+
]]></script>

_old_posts/community.textile

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
layout: default
3+
title: Community
4+
headtitle: Community -
5+
---
6+
h2. Blogs
7+
8+
* "Presentation by Jay tailor":http://scala.sh/squeryl-presentation-slides.pdf
9+
* "Presentation un Russian":http://www.youtube.com/watch?v=7FQtslXpbpY
10+
* "With play2 on Heroku":http://www.jamesward.com/2012/07/16/getting-started-with-play-2-scala-and-squeryl
11+
* "Squeryl with Java Experiment":http://lunajs.blogspot.com/2011/06/squeryl-with-java-experiment.html
12+
* "Setup example in Japanese":http://blog.twiwt.org/e/7e40ce
13+
* "Scala ORM with Squeryl - A simple getting started guide":http://blog.xebia.com/2011/06/scala-orm-with-squeryl/
14+
* "Getting Started – Scala Persistence with Squeryl":http://srirangan.net/2011-03-getting-started-%E2%80%93-scala-persistence-with-squeryl
15+
* "Scalatra, MySQL and Star Wars Droids":http://www.7sudos.com/blog/scalatra-mysql-and-star-wars-droids
16+
* "Interview with Maxime Lévesque":http://nikolajlindberg.blogspot.com/2010/09/interview-with-maxime-levesque-author.html
17+
* "What's in your stack ?":http://php.jglobal.com/blog/?p=1215
18+
* "I have settled on a new platform for webapps":http://www.alvarocarrasco.com/2010/12/i-have-settled-on-new-platform-for.html
19+
20+
21+
h2. The Squeryl Team
22+
23+
h3. Founder
24+
25+
* Maxime Lévesque
26+
27+
h3. Commiters
28+
29+
* David Whitaker
30+
* Marco Rico Gomez
31+
* Peter Brant
32+
33+
h3. Contributors
34+
35+
* Antti Tuppurainen
36+
* Christian Maslen
37+
* David Flemström
38+
* Alec Wysoker
39+
* Mitsutoshi Aoe
40+
* Rémy Roy
41+
* Michael Bayne
42+
* Ross Mellgren
43+
* Yuen Ho Wong
44+
* Michael Gottshalk
45+
* Joonas Javanainen
46+
* Sam Hendley
47+
48+
h2. Follow latest news on Twitter <a href="http://www.twitter.com/_squeryl"><img src="http://twitter-badges.s3.amazonaws.com/follow_bird-b.png" alt="Follow _squeryl on Twitter"/></a>
49+
50+
h2. Help
51+
52+
Help is available via the "Discussion Group":http://groups.google.com/group/squeryl
53+
54+
h2. Discussions and bug reports
55+
56+
Brainstorming, constructive criticism happens in the "Discussion Group":http://groups.google.com/group/squeryl
57+
58+
Implementation details are discussed in the "contributor's group":http://groups.google.com/group/squeryl-contributors
59+
60+
Issues and bugs should be submited in "Assembla issue tracking":http://www.assembla.com/spaces/squeryl/tickets
61+
62+
63+
The GitHub repo :
64+
65+
"http://github.com/max-l/Squeryl":http://github.com/max-l/Squeryl
66+
67+
Patches are gladly accepted from their original author.
68+
Along with any patches, please state that the patch is your original work and that you license the work to the Squeryl project under the project's (Apache 2.0) open source license.
69+
70+
h2. Building from Sources
71+
72+
Info on building is found "here":http://github.com/max-l/Squeryl
73+
74+
h2. Running the test suite
75+
76+
Testing on H2 doesn't require you to setup a database, if you build with "SBT":https://github.com/sbt/sbt you will have an "H2":http://www.h2database.com/ database ready to run the tests, and if the test succeds on H2, making it work on other DBs should be straight forward.

_old_posts/complete-example.textile

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
layout: default
3+
title: examples
4+
headtitle: Examples -
5+
---
6+
7+
8+
<script type="syntaxhighlighter" class="brush: scala"><![CDATA[
9+
10+
11+
package org.squeryl.demos;
12+
13+
import org.squeryl.PrimitiveTypeMode._
14+
import org.squeryl.adapters.H2Adapter
15+
import org.squeryl.{Session, KeyedEntity, Schema}
16+
17+
18+
// The root object of the schema. Inheriting KeyedEntity[T] is not mandatory
19+
// it just makes primary key methods available (delete and lookup) on tables.
20+
class MusicDbObject extends KeyedEntity[Long] {
21+
var id: Long = 0
22+
}
23+
24+
class Artist(var name:String) extends MusicDbObject {
25+
26+
// this returns a Query[Song] which is also an Iterable[Song] :
27+
def songs = from(MusicDb.songs)(s => where(s.artistId === id) select(s))
28+
29+
def newSong(title: String, filePath: Option[String]) =
30+
MusicDb.songs.insert(new Song(title, id, filePath))
31+
}
32+
33+
// Option[] members are mapped to nullable database columns,
34+
// otherwise they have a NOT NULL constraint.
35+
class Song(var title: String, var artistId: Long, var filePath: Option[String]) extends MusicDbObject {
36+
37+
// IMPORTANT : currently classes with Option[] members *must* provide a zero arg
38+
// constructor where every Option[T] member gets initialized with Some(t:T).
39+
// or else Squeryl will not be able to reflect the type of the field, and an exception will
40+
// be thrown at table instantiation time.
41+
def this() = this("", 0, Some(""))
42+
43+
// the schema can be imported in the scope, to lighten the syntax :
44+
import MusicDb._
45+
46+
// An alternative (shorter) syntax for single table queries :
47+
def artist = artists.where(a => a.id === artistId).single
48+
49+
// Another alternative for lookup by primary key, since Artist is a
50+
// KeyedEntity[Long], it's table has a lookup[Long](k: Long)
51+
// method available :
52+
def lookupArtist = artists.lookup(artistId)
53+
}
54+
55+
class Playlist(var name: String, var path: String) extends MusicDbObject {
56+
57+
import MusicDb._
58+
59+
// a two table join :
60+
def songsInPlaylistOrder =
61+
from(playlistElements, songs)((ple, s) =>
62+
where(ple.playlistId === id and ple.songId === s.id)
63+
select(s)
64+
orderBy(ple.songNumber asc)
65+
)
66+
67+
def addSong(s: Song) = {
68+
69+
// Note how this query can be implicitly converted to an Int since it returns
70+
// at most one row, this applies to all single column aggregate queries with no groupBy clause.
71+
// The nvl function in this example changed the return type to Int, from
72+
// Option[Int], since the 'max' function (like all aggregates, 'count' being the only exception).
73+
val nextSongNumber: Int =
74+
from(playlistElements)(ple =>
75+
where(ple.playlistId === id)
76+
compute(nvl(max(ple.songNumber), 0))
77+
)
78+
79+
playlistElements.insert(new PlaylistElement(nextSongNumber, id, s.id))
80+
}
81+
82+
// New concept : a group query with aggregate functions return GroupWithMeasures[K,M]
83+
// where K and M are tuples whose members correspond to the group by list and compute list
84+
// respectively.
85+
private def _songCountByArtistId =
86+
from(artists, songs)((a,s) =>
87+
where(a.id === s.artistId)
88+
groupBy(a.id)
89+
compute(count)
90+
)
91+
92+
// Queries are nestable just as they would in SQL
93+
def songCountForAllArtists =
94+
from(_songCountByArtistId, artists)((sca,a) =>
95+
where(sca.key === a.id)
96+
select((a, sca.measures))
97+
)
98+
99+
// Unlike SQL, a function that returns a query can be nested
100+
// as if it were a query, notice the nesting of 'songsOf'
101+
// allowing DRY persistence layers as reuse is enhanced.
102+
def latestSongFrom(artistId: Long) =
103+
from(songsOf(artistId))(s =>
104+
select(s)
105+
orderBy(s.id desc)
106+
).headOption
107+
108+
def songsOf(artistId: Long) =
109+
from(playlistElements, songs)((ple,s) =>
110+
where(id === ple.playlistId and ple.songId === s.id and s.artistId === artistId)
111+
select(s)
112+
)
113+
}
114+
115+
116+
class PlaylistElement(var songNumber: Int, var playlistId: Long, var songId: Long)
117+
118+
119+
object MusicDb extends Schema {
120+
121+
val songs = table[Song]
122+
val artists = table[Artist]
123+
val playlists = table[Playlist]
124+
val playlistElements = table[PlaylistElement]
125+
}
126+
127+
128+
129+
object KickTheTires {
130+
131+
import MusicDb._
132+
133+
//A Squeryl session is a thin wrapper over a JDBC connection :
134+
Class.forName("org.h2.Driver");
135+
val session = Session.create(
136+
java.sql.DriverManager.getConnection("jdbc:h2:~/test", "sa", ""),
137+
//Currently there are adapters for Oracle, Postgres, MySQL and H2 :
138+
new H2Adapter
139+
)
140+
141+
try {
142+
session.work {
143+
// database access code goes here
144+
test
145+
session.connection.commit
146+
}
147+
}
148+
catch {
149+
case e:Exception => session.connection.rollback
150+
}
151+
152+
def test = {
153+
154+
val herbyHancock = artists.insert(new Artist("Herby Hancock"))
155+
val ponchoSanchez = artists.insert(new Artist("Poncho Sanchez"))
156+
val mongoSantaMaria = artists.insert(new Artist("Mongo Santa Maria"))
157+
158+
val watermelonMan = herbyHancock.newSong("Watermelon Man", None)
159+
val besameMama = mongoSantaMaria.newSong("Besame Mama", Some("c:/MyMusic/besameMama.flac"))
160+
val freedomSound = ponchoSanchez.newSong("Freedom Sound", None)
161+
}
162+
}
163+
164+
]]></script>

0 commit comments

Comments
 (0)