scala/lift/pgsql-inet-model.scala
author Tomas Zeman <tomas@functionals.cz>
Mon, 27 Apr 2020 22:23:42 +0200
changeset 58 b36c5ed3c360
parent 4 5ef63a5d98b2
permissions -rw-r--r--
.bashrc.t450
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     1
/*
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     2
 * Copyright ...
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     3
 */
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     4
package example
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     5
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     6
import java.net.InetAddress
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     7
import net.liftweb.common._
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     8
import net.liftweb.mapper._
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     9
import net.liftweb.util._
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    10
import net.liftweb.util.Helpers._
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    11
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    12
object InetAddressHelpers extends InetAddressHelpers
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    13
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    14
trait InetAddressHelpers {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    15
  def normalize(inet: String): Box[String] = tryo {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    16
    InetAddress.getByName(inet).getHostAddress
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    17
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    18
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    19
  def valid_?(inet: String): Boolean = (inet != null) && (tryo {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    20
    InetAddress.getByName(inet)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    21
  } isDefined ) && (inet.length > 0)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    22
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    23
  def toBigInt(inet: InetAddress): BigInt = BigInt(1, inet.getAddress)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    24
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    25
  def toInet(s: String): Box[InetAddress] = s match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    26
    case null | "" => Empty
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    27
    case _ => tryo { InetAddress.getByName(s) }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    28
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    29
}
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    30
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    31
/**
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    32
 * Postgres specific <code>InetAddress</code> mapping
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    33
 * (maps to ''inet'' data type).
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    34
 * Always use <code>asInet</code> to get <code>InetAddress</code> instance.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    35
 */
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    36
abstract class MappedInetAddress[T<:Mapper[T]](owner: T) extends
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    37
  MappedString[T](owner, 128) with InetAddressHelpers {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    38
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    39
  override def setFilter = normalizeFilter _ :: super.setFilter
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    40
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    41
  override def validate = (valid_?(i_is_!) match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    42
    case true => Nil
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    43
    case false => List(FieldError(this, "Invalid IP address"))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    44
  }) ::: super.validate
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    45
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    46
  def normalizeFilter(inet: String): String = inet match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    47
    case null | "" => null
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    48
    case s => normalize(s) openOr null
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    49
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    50
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    51
  def asInet: Box[InetAddress] = toInet(is)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    52
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    53
  override def targetSQLType = Types.OTHER
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    54
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    55
  override def fieldCreatorString(d: DriverType, colName: String) = d match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    56
    case _d: BasePostgreSQLDriver => colName + " inet"
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    57
    case _ => super.fieldCreatorString(d, colName)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    58
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    59
}
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    60
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    61
/**
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    62
 * Caution: getters may return <code>null</code> value.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    63
 * Always use <code>asInet</code>.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    64
 */
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    65
abstract class MappedNullableInetAddress[T<:Mapper[T]](owner: T) extends
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    66
  MappedInetAddress[T](owner) {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    67
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    68
  override def defaultValue = null
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    69
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    70
  override def validate = i_is_! match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    71
    case null | "" => Nil
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    72
    case _ => super.validate
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    73
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    74
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    75
  override def dbNotNull_? = false
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    76
}
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    77
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    78
/**
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    79
 * IP network mapper via its start/end fields.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    80
 * Implemented validation of IP overlaps, parent network, start, end.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    81
 * Maintains network relationships (sub-net/super-net) and updates
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    82
 * parent field accordingly.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    83
 */
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    84
object ExampleNetwork extends ExampleNetwork with
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    85
  LongKeyedMetaMapper[ExampleNetwork] with LongCRUDify[ExampleNetwork] {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    86
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    87
  override def validation: List[ExampleNetwork => List[FieldError]] = 
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    88
    startLtEnd _ :: checkOverlap _ :: super.validation
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    89
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    90
  def startLtEnd(n: ExampleNetwork): List[FieldError] = (for {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    91
    s <- n.start.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    92
    e <- n.end.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    93
  } yield (toBigInt(s) < toBigInt(e))) match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    94
    case Full(true) => Nil
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    95
    case Full(false) =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    96
      List(FieldError(n.start, "Start must be below end"))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    97
    case _ =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    98
      List(FieldError(n.start, S ? "Can't compare start/end IP"))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    99
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   100
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   101
  def checkOverlap(net: ExampleNetwork): List[FieldError] = {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   102
    def run(f: MappedInetAddress[ExampleNetwork]) = {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   103
      findAll(inNet(f):_*) filter {!_.comparePrimaryKeys(net)} filter { n =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   104
        net.isSubnetOf(n) match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   105
          case f: Failure => true
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   106
          case _ => false
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   107
      }} map { n =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   108
        FieldError(f, "Overlaps with: " + n.start + " - " + n.end)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   109
      }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   110
    }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   111
    run(net.start) ::: run(net.end)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   112
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   113
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   114
  override def beforeSave = List(n => n.parent(findParent(a)))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   115
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   116
  override def afterSave = List(n => children(n.parent.obj) foreach { child =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   117
    child.parent(findParent(child)).save
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   118
  })
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   119
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   120
  override def afterDelete = List(n => children(Full(n)) foreach { child =>
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   121
    child.parent(findParent(child)).save
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   122
  })
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   123
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   124
  def findParent(net: ExampleNetwork): Box[ExampleNetwork] =
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   125
  findAll(inNet(net):_*) filter {!_.comparePrimaryKeys(net)} sort {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   126
    (n1, n2) => (for {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   127
      s1 <- n1.size
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   128
      s2 <- n2.size
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   129
  } yield s1 < s2) openOr true } firstOption
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   130
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   131
  import OprEnum._
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   132
  def inNet(inet: MappedInetAddress[ExampleNetwork]) = List(
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   133
    Cmp(start, <=, Full(inet.is), Empty, Empty),
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   134
    Cmp(end, >=, Full(inet.is), Empty, Empty)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   135
  )
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   136
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   137
  def inNet(net: ExampleNetwork): List[QueryParam[ExampleNetwork]] =
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   138
    inNet(net.start) ::: inNet(net.end)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   139
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   140
  def getByNet(s: String, e: String) = Box(findAll(By(start, s), By(end, e)))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   141
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   142
  def children(n: Box[ExampleNetwork]) = findAll(By(parent, n))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   143
}
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   144
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   145
class ExampleNetwork extends LongKeyedMapper[ExampleNetwork] with IdPK
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   146
  with InetAddressHelpers {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   147
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   148
  override def getSingleton = ExampleNetwork
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   149
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   150
  object start extends MappedInetAddress(this)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   151
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   152
  object end extends MappedInetAddress(this)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   153
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   154
  object parent extends LongMappedMapper(this, ExampleNetwork) {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   155
    override def dbIncludeInForm_? = false
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   156
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   157
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   158
  def size: Box[BigInt] = for {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   159
    s <- start.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   160
    e <- end.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   161
  } yield toBigInt(e) - toBigInt(s) + 1
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   162
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   163
  /**
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   164
   * Checks if this network is subnet of the <code>other</code>.
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   165
   * @return true if this is subnet of the other
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   166
   *         false if this is supernet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   167
   *         empty not related at all
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   168
   *         failure if can't compare or network overlap
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   169
   */
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   170
  def isSubnetOf(other: ExampleNetwork): Box[Boolean] = {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   171
    def inside(what: BigInt, from: BigInt, to: BigInt): Boolean =
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   172
      (from <= what) && (what <= to)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   173
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   174
    (for {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   175
      si <- start.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   176
      ei <- end.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   177
      osi <- other.start.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   178
      oei <- other.end.asInet
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   179
    } yield {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   180
      val s = toBigInt(si)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   181
      val e = toBigInt(ei)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   182
      val os = toBigInt(osi)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   183
      val oe = toBigInt(oei)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   184
      val s_inside = inside(s, os, oe)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   185
      val e_inside = inside(e, os, oe)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   186
      val os_inside = inside(os, s, e)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   187
      val oe_inside = inside(oe, s, e)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   188
      (s_inside, e_inside, os_inside, oe_inside) match {
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   189
        case (true, true, _, _) => Full(true)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   190
        case (_, _, true, true) => Full(false)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   191
        case (false, false, false, false) => Empty
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   192
        case (_, _, _, _) => Failure("IP address overlap with: " + other)
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   193
      }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   194
    }).openOr(Failure("Failed to obtain inet addresses: this: " + this +
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   195
      ", other: " + other))
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   196
  }
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   197
}
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   198
5ef63a5d98b2 Lift: MappedInetAddress, Inet networks hierarchy mapper
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
   199
// vim: set ts=2 sw=2 et: