Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Data Sources take two type parameters:
import cats.data.NonEmptyList

trait DataSource[Identity, Result]{
def name: String
def fetchOne(id: Identity): Query[Option[Result]]
def fetchMany(ids: NonEmptyList[Identity]): Query[Map[Identity, Result]]
}
Expand All @@ -58,6 +59,8 @@ import cats.instances.list._
import fetch._

implicit object ToStringSource extends DataSource[Int, String]{
override def name = "ToString"

override def fetchOne(id: Int): Query[Option[String]] = {
Query.sync({
println(s"[${Thread.currentThread.getId}] One ToString $id")
Expand Down Expand Up @@ -97,7 +100,7 @@ Let's run it and wait for the fetch to complete:

```scala
fetchOne.runA[Id]
// [97] One ToString 1
// [44] One ToString 1
// res3: cats.Id[String] = 1
```

Expand Down Expand Up @@ -127,6 +130,8 @@ This time, instead of creating the results with `Query#sync` we are going to do

```scala
implicit object LengthSource extends DataSource[String, Int]{
override def name = "Length"

override def fetchOne(id: String): Query[Option[Int]] = {
Query.async((ok, fail) => {
println(s"[${Thread.currentThread.getId}] One Length $id")
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import catext.Dependencies._
val dev = Seq(Dev("47 Degrees (twitter: @47deg)", "47 Degrees"))
val gh = GitHubSettings("com.fortysevendeg", "fetch", "47 Degrees", apache)

addCommandAlias("makeDocs", ";docs/tut;docs/makeSite")
addCommandAlias("makeDocs", ";readme/tut;docs/tut;docs/makeSite")

pgpPassphrase := Some(sys.env.getOrElse("PGP_PASSPHRASE", "").toCharArray)
pgpPublicRing := file(s"${sys.env.getOrElse("PGP_FOLDER", ".")}/pubring.gpg")
Expand Down
9 changes: 6 additions & 3 deletions docs/src/tut/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ In order to tell Fetch how to retrieve data, we must implement the `DataSource`
import cats.data.NonEmptyList

trait DataSource[Identity, Result]{
def name: String
def fetchOne(id: Identity): Query[Option[Result]]
def fetchMany(ids: NonEmptyList[Identity]): Query[Map[Identity, Result]]
}
Expand Down Expand Up @@ -126,7 +127,7 @@ val userDatabase: Map[UserId, User] = Map(
)

implicit object UserSource extends DataSource[UserId, User]{
override def name = "User data source"
override def name = "User"

override def fetchOne(id: UserId): Query[Option[User]] = {
Query.sync({
Expand Down Expand Up @@ -155,6 +156,8 @@ of `fetchMany`. Note that it will use the `fetchOne` implementation for requesti

```tut:silent
implicit object UnbatchedSource extends DataSource[Int, Int]{
override def name = "Unbatched"

override def fetchOne(id: Int): Query[Option[Int]] = {
Query.sync(Option(id))
}
Expand Down Expand Up @@ -338,7 +341,7 @@ val postDatabase: Map[PostId, Post] = Map(
)

implicit object PostSource extends DataSource[PostId, Post]{
override def name = "Post data source"
override def name = "Post"

override def fetchOne(id: PostId): Query[Option[Post]] = {
Query.sync({
Expand Down Expand Up @@ -371,7 +374,7 @@ We'll implement a data source for retrieving a post topic given a post id.

```tut:silent
implicit object PostTopicSource extends DataSource[Post, PostTopic]{
override def name = "Post topic data source"
override def name = "Post topic"

override def fetchOne(id: Post): Query[Option[PostTopic]] = {
Query.sync({
Expand Down
9 changes: 7 additions & 2 deletions docs/src/tut/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,24 @@ Data Sources take two type parameters:
import cats.data.NonEmptyList

trait DataSource[Identity, Result]{
def name: String
def fetchOne(id: Identity): Query[Option[Result]]
def fetchMany(ids: NonEmptyList[Identity]): Query[Map[Identity, Result]]
}
```

Note that when we create a query we can compute its result right away, defer its evaluation or make it asynchronous. Returning `Query` instances from the fetch methods allows us to abstract from the target result type and to run it synchronously or asynchronously.

We'll implement a dummy data source that can convert integers to strings. For convenience, we define a `fetchString` function that lifts identities (`Int` in our dummy data source) to a `Fetch`.
We'll implement a dummy data source that can convert integers to strings. For convenience, we define a `fetchString` function that lifts identities (`Int` in our dummy data source) to a `Fetch`.

```tut:silent
import cats.data.NonEmptyList
import cats.instances.list._
import fetch._

implicit object ToStringSource extends DataSource[Int, String]{
override def name = "ToString"

override def fetchOne(id: Int): Query[Option[String]] = {
Query.sync({
println(s"[${Thread.currentThread.getId}] One ToString $id")
Expand Down Expand Up @@ -135,6 +138,8 @@ This time, instead of creating the results with `Query#sync` we are going to do

```tut:silent
implicit object LengthSource extends DataSource[String, Int]{
override def name = "Length"

override def fetchOne(id: String): Query[Option[Int]] = {
Query.async((ok, fail) => {
println(s"[${Thread.currentThread.getId}] One Length $id")
Expand All @@ -152,7 +157,7 @@ implicit object LengthSource extends DataSource[String, Int]{
def fetchLength(s: String): Fetch[Int] = Fetch(s)
```

And now we can easily receive data from the two sources in a single fetch.
And now we can easily receive data from the two sources in a single fetch.

```tut:silent
val fetchMulti: Fetch[(String, Int)] = (fetchString(1) |@| fetchLength("one")).tupled
Expand Down
2 changes: 1 addition & 1 deletion shared/src/main/scala/datasource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ trait DataSource[I, A] {

/** The name of the data source.
*/
def name: DataSourceName = this.getClass.getName
def name: DataSourceName
override def toString: String = name

/**
Expand Down
5 changes: 5 additions & 0 deletions tut/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Data Sources take two type parameters:
import cats.data.NonEmptyList

trait DataSource[Identity, Result]{
def name: String
def fetchOne(id: Identity): Query[Option[Result]]
def fetchMany(ids: NonEmptyList[Identity]): Query[Map[Identity, Result]]
}
Expand All @@ -65,6 +66,8 @@ import cats.instances.list._
import fetch._

implicit object ToStringSource extends DataSource[Int, String]{
override def name = "ToString"

override def fetchOne(id: Int): Query[Option[String]] = {
Query.sync({
println(s"[${Thread.currentThread.getId}] One ToString $id")
Expand Down Expand Up @@ -130,6 +133,8 @@ This time, instead of creating the results with `Query#sync` we are going to do

```tut:silent
implicit object LengthSource extends DataSource[String, Int]{
override def name = "Length"

override def fetchOne(id: String): Query[Option[Int]] = {
Query.async((ok, fail) => {
println(s"[${Thread.currentThread.getId}] One Length $id")
Expand Down