blob: b1aba3e9730419f1a5238ca0ac3c0941eba04451 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.s2graph.core.schema
import play.api.libs.json.Json
import scalikejdbc._
import scala.util.Try
object ColumnMeta extends SQLSyntaxSupport[ColumnMeta] {
import Schema._
val className = ColumnMeta.getClass.getSimpleName
val timeStampSeq = 0.toByte
val countSeq = -1.toByte
val lastModifiedAtColumnSeq = 0.toByte
val lastModifiedAtColumn = ColumnMeta(Some(0), 0, "lastModifiedAt", lastModifiedAtColumnSeq, "long", "-1")
val maxValue = Byte.MaxValue
val timestamp = ColumnMeta(None, -1, "_timestamp", timeStampSeq.toByte, "long", "-1")
val reservedMetas = Seq(timestamp, lastModifiedAtColumn)
val reservedMetaNamesSet = reservedMetas.map(_.name).toSet
def isValid(columnMeta: ColumnMeta): Boolean =
columnMeta.id.isDefined && columnMeta.id.get > 0 && columnMeta.seq >= 0
def valueOf(rs: WrappedResultSet): ColumnMeta = {
ColumnMeta(Some(rs.int("id")), rs.int("column_id"), rs.string("name"),
rs.byte("seq"), rs.string("data_type").toLowerCase(), rs.string("default_value"), rs.boolean("store_in_global_index"))
}
def findById(id: Int)(implicit session: DBSession = AutoSession) = {
val cacheKey = className + "id=" + id
withCache(cacheKey) {
sql"""select * from column_metas where id = ${id}""".map { rs => ColumnMeta.valueOf(rs) }.single.apply
}.get
}
def findAllByColumn(columnId: Int, useCache: Boolean = true)(implicit session: DBSession = AutoSession) = {
// val cacheKey = s"columnId=$columnId"
val cacheKey = className + "columnId=" + columnId
if (useCache) {
withCaches(cacheKey)( sql"""select *from column_metas where column_id = ${columnId} order by seq ASC"""
.map { rs => ColumnMeta.valueOf(rs) }.list.apply())
} else {
sql"""select * from column_metas where column_id = ${columnId} order by seq ASC"""
.map { rs => ColumnMeta.valueOf(rs) }.list.apply()
}
}
def findByName(columnId: Int, name: String, useCache: Boolean = true)(implicit session: DBSession = AutoSession) = {
// val cacheKey = s"columnId=$columnId:name=$name"
val cacheKey = className + "columnId=" + columnId + ":name=" + name
lazy val sql = sql"""select * from column_metas where column_id = ${columnId} and name = ${name}"""
.map { rs => ColumnMeta.valueOf(rs) }.single.apply()
if (useCache) withCache(cacheKey)(sql)
else sql
}
def insert(columnId: Int, name: String, dataType: String, defaultValue: String, storeInGlobalIndex: Boolean = false)(implicit session: DBSession = AutoSession) = {
val ls = findAllByColumn(columnId, false)
val seq = ls.size + 1
if (seq <= maxValue) {
sql"""insert into column_metas(column_id, name, seq, data_type, default_value, store_in_global_index)
select ${columnId}, ${name}, ${seq}, ${dataType}, ${defaultValue}, ${storeInGlobalIndex}"""
.updateAndReturnGeneratedKey.apply()
}
}
def findOrInsert(columnId: Int,
name: String,
dataType: String,
defaultValue: String,
storeInGlobalIndex: Boolean = false,
useCache: Boolean = true)(implicit session: DBSession = AutoSession): ColumnMeta = {
findByName(columnId, name, useCache) match {
case Some(c) => c
case None =>
insert(columnId, name, dataType, defaultValue, storeInGlobalIndex)
expireCache(className + s"columnId=$columnId:name=$name")
findByName(columnId, name).get
}
}
def findByIdAndSeq(columnId: Int, seq: Byte, useCache: Boolean = true)(implicit session: DBSession = AutoSession) = {
val cacheKey = className + "columnId=" + columnId + ":seq=" + seq
lazy val columnMetaOpt = sql"""
select * from column_metas where column_id = ${columnId} and seq = ${seq}
""".map { rs => ColumnMeta.valueOf(rs) }.single.apply()
if (useCache) withCache(cacheKey)(columnMetaOpt)
else columnMetaOpt
}
def delete(id: Int)(implicit session: DBSession = AutoSession) = {
val columnMeta = findById(id)
val (columnId, name) = (columnMeta.columnId, columnMeta.name)
sql"""delete from column_metas where id = ${id}""".execute.apply()
val cacheKeys = List(s"id=$id", s"columnId=$columnId:name=$name", s"colunmId=$columnId")
cacheKeys.foreach { key =>
expireCache(className + key)
expireCaches(className + key)
}
}
def findAll()(implicit session: DBSession = AutoSession) = {
val ls = sql"""select * from column_metas""".map { rs => ColumnMeta.valueOf(rs) }.list().apply()
putsToCacheOption(ls.flatMap { x =>
Seq(
s"id=${x.id.get}",
s"columnId=${x.columnId}:name=${x.name}",
s"columnId=${x.columnId}:seq=${x.seq}"
).map(cacheKey => (className + cacheKey, x))
})
putsToCaches(ls.groupBy(x => x.columnId).map { case (columnId, ls) =>
val cacheKey = className + s"columnId=${columnId}"
(cacheKey -> ls)
}.toList)
ls
}
def updateStoreInGlobalIndex(id: Int, storeInGlobalIndex: Boolean)(implicit session: DBSession = AutoSession): Try[Long] = Try {
sql"""
update column_metas set store_in_global_index = ${storeInGlobalIndex} where id = ${id}
""".updateAndReturnGeneratedKey.apply()
}
}
case class ColumnMeta(id: Option[Int],
columnId: Int,
name: String,
seq: Byte,
dataType: String,
defaultValue: String,
storeInGlobalIndex: Boolean = false) {
lazy val toJson = Json.obj("name" -> name, "dataType" -> dataType)
override def equals(other: Any): Boolean = {
if (!other.isInstanceOf[ColumnMeta]) false
else {
val o = other.asInstanceOf[ColumnMeta]
// labelId == o.labelId &&
seq == o.seq
}
}
override def hashCode(): Int = seq.toInt
}