2014-09-23 3 views
1

Slick의 해제 된 Embedding을 사용하여 AbstractTable을 확장하는 클래스를 정의하고 일부 기본 키가 여러 열을 스패닝합니다. 예를 들어 코드에TableElementType 튜플의 PrimaryKey 투영을 얻는 방법은 무엇입니까?

class Foo extends AbstractTable[(some, tuple, type)](tag, name) 
{ 
    def col1 = ... 
    def col2 = ... 
    def col3 = ... 
    def * = (col1, col2, col3) 
    def pk = primaryKey(name, (col1, col2)) 
    ... 
} 

어딘가에, 내가 그 기본 키에 해당하는 기본 키 참조를 보유 (문제의 코드는 일반과 특정 테이블과 열이 정의되어있는 지식에 의존해서는 안됩니다) . 또한 * 투영에 정의 된대로이 테이블의 행에 해당하는 TableElementType 튜플에 대한 참조를 보유합니다.

프로그래밍 방식으로 해당 요소의 기본 키 투영을 얻으려면 어떻게해야합니까? 즉, PrimaryKey 및 TableElementType 참조가 인수로 주어진다면이 예제에서 (val1, val2, val3) TableElementType 튜플에서 (val1, val2) 튜플을 가져와야합니다. 나는 Slick 문서에서 쉽게 달성 할 수있는 방법을 찾지 못했습니다.

답변

0

AbstractTable 다른 서명이,이 3 개 매개 변수를 사용하지 2 :

abstract class AbstractTable[T](val tableTag: Tag, val schemaName: Option[String], val tableName: String) extends ColumnBase[T] 
여기

나는 편의를 위해 Table 확장하고있어, 당신이 할 수있는 일은 당신의 테이블 형식 매개 변수에 모양을 비틀 수 있습니다 :

당신이 (String, String, String)이있는 경우 다음 투사 기능도 이렇게 정의해야한다는
class Foo(tag: Tag) extends Table[((String, String), String)](tag, "Foo") { 
    def col1 = column[String]("c1") 
    def col2 = column[String]("c2") 
    def col3 = column[String]("c3") 
    def * = ((col1, col2), col3) 
    def pk = primaryKey("pk", (col1, col2)) 
} 

참고 :

def * = (col1, col2, col3) 
// this below doesn't match the given shape: 
// def * = ((col1, col2), col3) 
,

당신은 단지 사용자 정의 메소드를 정의하지 않으려면 :

def someF(results: List[(String, String, String)]): List[((String, String), String)] = { 
    results.map { case(a,b,c) => ((a,b),c) } 
} 

순간에 내가 사용할 수있는 데이터베이스가없는 있지만 컴파일 때문에 코드는 테스트되지 않은 것입니다.

편집 : 나는

def tupleKeys[T <: Table[S], S](table: TableQuery[T]): Tuple2[Option[PrimaryKey], Option[PrimaryKey]] = { 
    val keys: List[PrimaryKey] = table.baseTableRow.primaryKeys.toList 
    if(keys.length == 2) (Option(keys(0)), Option(keys(1))) 
    else (Option(keys(0)), None) 
} 

을하지만 말했듯이, 당신은 튜플은 길이가 고정 된 반면 스크립트를 실행하기 전에 당신이 얼마나 많은 키 모른다 :

이 사용할 수 두 개의 키가 있거나 없을 수도 있고 다른 유형이기 때문에 Tuple1 또는 Tuple2을 반환 할 수 있으므로 옵션에서 값을 래핑했습니다.이 방법을 투영 함수에 사용하여 키 모양을 비틀었지만 여전히 변하지는 않습니다 당신이 원하는대로 동적으로.

+0

감사합니다. 그러나 이것은 내가 요구 한 것이 아닙니다. 나는 심지어 구체적인 테이블을위한 클래스를 작성하기도하지 않았다. 일반적인 데이터 액세스 레이어를 작성 중이며 기본 키 투영을 얻는 일반적인 방법에 관심이 있습니다. 기본 클래스에 PrimaryKey 및 T # TableElementType이라는 두 개의 인수를 사용하는 메서드와 같은 것이 있으며 기본 키에 포함 된 열에 대해서만 지정된 요소 값의 튜플을 반환합니다. – silverberry

+0

당신이 무엇을 요구하는지는 쉽게 구현할 수 없습니다. 왜냐하면 터플 길이가 인코딩되어 있기 때문입니다 (예 :'Tuple2','Tuple3' 등). 당신이 할 수있는 일은 테이블 객체를 정의하고 반복자에서 기본 키를 얻는 것입니다 : 'TableQuery [Foo] .baseTableRow.primaryKeys', form here 여기 튜플로 돌연변이를 만드는 법을 설명 할 수는 없지만, 아마도 엉성한 것은 관련이 있습니다.하지만 저는 라이브러리 전문가가 아닙니다. –

+0

OK, 알겠습니다. 물론 기본 키를 반복합니다. 더 간단한 질문은 어떻습니까? 말하자면, T # TableElementType 요소와 Column [V] 열이 있습니다. 해당 요소에 대해 프로그래밍 방식으로 해당 열의 값을 얻으려면 어떻게해야합니까? – silverberry