Skip to content

Instantly share code, notes, and snippets.

@dt
Created June 15, 2012 15:22
Show Gist options
  • Save dt/2937002 to your computer and use it in GitHub Desktop.
Save dt/2937002 to your computer and use it in GitHub Desktop.
non-circular dep fks
package demo
package ids {
import record.Id
object FooId extends Id[Int]
object BarId extends Id[Int]
object BazId extends Id[String]
}
package foomodel {
import barmodel.fk.HasBarFK
import bazmodel.fk.HasBazFK
import ids.FooId
class Foo(id: FooId.Type) extends HasBarFK with HasBazFK
}
package barmodel {
import ids.BarId
import bazmodel.fk.HasBazFK
package fk { trait HasBarFK { object barId extends record.IntFKField(BarId.tag) }}
trait HasBar { def bar: Bar }
class Bar(id: BarId.Type) extends HasBazFK { def nameBar = "Bar" + id}
}
package bazmodel {
import barmodel.fk.HasBarFK
import ids.BazId
package fk { trait HasBazFK { object bazId extends record.StringFKField(BazId.tag) }}
trait HasBaz { def baz: Baz }
class Baz(id: BazId.Type) extends HasBarFK { def nameBaz = "Baz" + id }
}
object FKDemo {
import foomodel.Foo
import barmodel.Bar
import bazmodel.Baz
val f1 = new Foo(ids.FooId(1))
val bar = new Bar(f1.barId.fk)
val baz = new Baz(f1.bazId.fk)
}
package record {
trait IdTagger[T, U] { def apply(in: T) = in.asInstanceOf[U]}
trait Id[T] {
type Type = T with Object { type Tag = Object }
def apply(in: T): Type = tag.apply(in)
object tag extends IdTagger[T, Type]
}
trait Field[T] { def value: T }
trait IntField extends Field[Int] {override def value = 5 }
trait StringField extends Field[String] { override def value = "6"}
trait FK[IdT] { def fk: IdT }
class IntFKField[IdT](tagger: IdTagger[Int, IdT]) extends FK[IdT] with IntField { def fk = tagger(value) }
class StringFKField[IdT](tagger: IdTagger[String, IdT]) extends FK[IdT] with StringField { def fk = tagger(value) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment