Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the code for creating case classes from rows #103

Merged
merged 3 commits into from
Oct 24, 2017
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
82 changes: 0 additions & 82 deletions core/src/main/scala/mapper/package.scala

This file was deleted.

57 changes: 57 additions & 0 deletions core/src/main/scala/query/FieldLister.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.cassandra
package query

import shapeless._
import shapeless.labelled.FieldType

trait FieldLister[A] {
val list: List[String]
}

trait FieldListerPrimitive {
implicit def primitiveFieldLister[K <: Symbol, H, T <: HList](
implicit witness: Witness.Aux[K],
tLister: FieldLister[T]): FieldLister[FieldType[K, H] :: T] =
FieldLister[FieldType[K, H] :: T](witness.value.name :: tLister.list)
}

trait FieldListerGeneric extends FieldListerPrimitive {

implicit def genericLister[A, R](
implicit gen: LabelledGeneric.Aux[A, R],
lister: Lazy[FieldLister[R]]): FieldLister[A] = FieldLister[A](lister.value.list)

implicit val hnilLister: FieldLister[HNil] = FieldLister[HNil](Nil)

}

object FieldLister extends FieldListerGeneric {
def apply[A](l: List[String]): FieldLister[A] = new FieldLister[A] {
override val list: List[String] = l
}
}

object FieldListerExpanded extends FieldListerGeneric {

implicit def hconsLister[K, H, T <: HList](
implicit hLister: Lazy[FieldLister[H]],
tLister: FieldLister[T]): FieldLister[FieldType[K, H] :: T] =
FieldLister[FieldType[K, H] :: T](hLister.value.list ++ tLister.list)

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

package freestyle.cassandra
package mapper
package query.mapper

trait ByteBufferMapper[A] {
def map(a: A): List[FieldMapper]
Expand Down
66 changes: 66 additions & 0 deletions core/src/main/scala/query/mapper/ByteBufferToField.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.cassandra
package query.mapper

import cats.MonadError
import freestyle.cassandra.codecs.ByteBufferCodec
import freestyle.cassandra.query._
import shapeless._
import shapeless.labelled.{FieldBuilder, FieldType}
import shapeless.{::, HList, Witness}

trait FromReader[A] {
def apply[M[_]](reader: ByteBufferReader)(implicit ME: MonadError[M, Throwable]): M[A]
}

trait GenericFromReader {

implicit val hnilFromReader: FromReader[HNil] = new FromReader[HNil] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[HNil] = ME.pure(HNil)
}

implicit def hconsFromReader[K <: Symbol, V, L <: HList](
implicit
witness: Witness.Aux[K],
codec: ByteBufferCodec[V],
grT: FromReader[L],
printer: Printer): FromReader[FieldType[K, V] :: L] =
new FromReader[FieldType[K, V] :: L] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[FieldType[K, V] :: L] = {
val newName = printer.print(witness.value.name)
ME.flatMap(reader.read(newName)) { byteBuffer =>
ME.map2(codec.deserialize(byteBuffer), grT(reader)) {
case (result, l) => new FieldBuilder[K].apply(result) :: l
}
}
}
}

implicit def productFromReader[A, L <: HList](
implicit
gen: LabelledGeneric.Aux[A, L],
grL: FromReader[L]): FromReader[A] =
new FromReader[A] {
override def apply[M[_]](reader: ByteBufferReader)(
implicit ME: MonadError[M, Throwable]): M[A] = ME.map(grL(reader))(gen.from)
}
}

object GenericFromReader extends GenericFromReader
75 changes: 75 additions & 0 deletions core/src/main/scala/query/mapper/FieldToByteBuffer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.cassandra
package query.mapper

import java.nio.ByteBuffer

import cats.MonadError
import freestyle.cassandra.codecs.ByteBufferCodec
import shapeless._
import shapeless.labelled.FieldType

abstract class FieldMapper(val name: String) {
def serialize[M[_]](implicit E: MonadError[M, Throwable]): M[ByteBuffer]
}

trait FieldListMapper[A] {
def map(a: A): List[FieldMapper]
}

trait FieldMapperPrimitive {

implicit def primitiveFieldMapper[K <: Symbol, H, T <: HList](
implicit witness: Witness.Aux[K],
codec: Lazy[ByteBufferCodec[H]],
tMapper: FieldListMapper[T]): FieldListMapper[FieldType[K, H] :: T] = {
val fieldName = witness.value.name
FieldListMapper { hlist =>
val fieldMapper = new FieldMapper(fieldName) {
override def serialize[M[_]](implicit E: MonadError[M, Throwable]): M[ByteBuffer] =
codec.value.serialize(hlist.head)
}
fieldMapper :: tMapper.map(hlist.tail)
}
}
}

trait FieldMapperGeneric extends FieldMapperPrimitive {

implicit def genericMapper[A, R](
implicit gen: LabelledGeneric.Aux[A, R],
mapper: Lazy[FieldListMapper[R]]): FieldListMapper[A] =
FieldListMapper(value => mapper.value.map(gen.to(value)))

implicit val hnilMapper: FieldListMapper[HNil] = FieldListMapper[HNil](_ => Nil)

}

object FieldListMapper extends FieldMapperGeneric {
def apply[A](f: (A) => List[FieldMapper]): FieldListMapper[A] = new FieldListMapper[A] {
override def map(a: A): List[FieldMapper] = f(a)
}
}

object FieldMapperExpanded extends FieldMapperGeneric {

implicit def hconsMapper[K, H, T <: HList](
implicit hMapper: Lazy[FieldListMapper[H]],
tMapper: FieldListMapper[T]): FieldListMapper[FieldType[K, H] :: T] =
FieldListMapper(hlist => hMapper.value.map(hlist.head) ++ tMapper.map(hlist.tail))
}
45 changes: 13 additions & 32 deletions core/src/main/scala/query/query.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,30 @@

package freestyle.cassandra

import shapeless._
import shapeless.labelled.FieldType
import java.nio.ByteBuffer

import cats.MonadError

package object query {

trait FieldLister[A] {
val list: List[String]
trait ByteBufferReader {
def read[M[_]](name: String)(implicit ME: MonadError[M, Throwable]): M[ByteBuffer]
}

trait FieldListerPrimitive {
implicit def primitiveFieldLister[K <: Symbol, H, T <: HList](
implicit witness: Witness.Aux[K],
tLister: FieldLister[T]): FieldLister[FieldType[K, H] :: T] =
new FieldLister[FieldType[K, H] :: T] {
override val list: List[String] = witness.value.name :: tLister.list
}
trait Printer {
def print(name: String): String
}

trait FieldListerGeneric extends FieldListerPrimitive {

implicit def genericLister[A, R](
implicit gen: LabelledGeneric.Aux[A, R],
lister: Lazy[FieldLister[R]]): FieldLister[A] = new FieldLister[A] {
override val list: List[String] = lister.value.list
}

implicit val hnilLister: FieldLister[HNil] = new FieldLister[HNil] {
override val list: List[String] = Nil
object Printer {
def apply(f: String => String): Printer = new Printer {
override def print(name: String): String = f(name)
}

}

object FieldLister extends FieldListerGeneric

object FieldListerExpanded extends FieldListerGeneric {
val identityPrinter: Printer = Printer(identity)

implicit def hconsLister[K, H, T <: HList](
implicit hLister: Lazy[FieldLister[H]],
tLister: FieldLister[T]): FieldLister[FieldType[K, H] :: T] =
new FieldLister[FieldType[K, H] :: T] {
override val list: List[String] = hLister.value.list ++ tLister.list
}
val lowerCasePrinter: Printer = Printer(_.toLowerCase)

}
val upperCasePrinter: Printer = Printer(_.toUpperCase)

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

package freestyle.cassandra
package mapper
package query.mapper

import java.nio.ByteBuffer

Expand Down
Loading