2016-09-08 4 views
0

Я пытаюсь просто вставить элемент в базу данных, не имея на экране флага autoinc.Slick 3.1.1 вставить элемент в базу данных без AutoInc

Вот определение таблицы, у меня есть все соответствующие картографы, определенные:

class BlockHeaderTable(tag: Tag) extends Table[BlockHeader](tag,"block_headers") { 

    def hash = column[DoubleSha256Digest]("hash", O.PrimaryKey) 

    def version = column[UInt32]("version") 

    def previousBlockHash = column[DoubleSha256Digest]("previous_block_hash") 

    def merkleRootHash = column[DoubleSha256Digest]("merkle_root_hash") 

    def time = column[UInt32]("time") 

    def nBits = column[UInt32]("n_bits") 

    def nonce = column[UInt32]("nonce") 

    def * = (hash, version, previousBlockHash, merkleRootHash, time, nBits, nonce).<>[BlockHeader, 
    (DoubleSha256Digest, UInt32, DoubleSha256Digest, DoubleSha256Digest, UInt32, UInt32, UInt32)](blockHeaderApply,blockHeaderUnapply) 
} 

Я пытаюсь создать простую функцию вставки для этой таблицы. Вот моя попытка:

override val table = TableQuery[BlockHeaderTable] 

    def create(blockHeader: BlockHeader): Future[BlockHeader] = { 
    val insertAction = table += blockHeader 
    database.run(insertAction) 
    } 

, и я получаю эту ошибку для типов:

[email protected]:~/dev/bitcoins-spv-node$ sbt compile 
[info] Loading project definition from /home/chris/dev/bitcoins-spv-node/project 
[info] Set current project to bitcoins-spv-node (in build file:/home/chris/dev/bitcoins-spv-node/) 
[info] Compiling 1 Scala source to /home/chris/dev/bitcoins-spv-node/target/scala-2.11/classes... 
[error] /home/chris/dev/bitcoins-spv-node/src/main/scala/org/bitcoins/spvnode/models/BlockHeaderDAO.scala:30: type mismatch; 
[error] found : slick.profile.FixedSqlAction[Boolean,slick.dbio.NoStream,slick.dbio.Effect.Write] 
[error] required: slick.dbio.DBIOAction[org.bitcoins.core.protocol.blockchain.BlockHeader,slick.dbio.NoStream,Nothing] 
[error]  database.run(insertAction) 
[error]    ^
[error] one error found 
[error] (compile:compileIncremental) Compilation failed 
[error] Total time: 3 s, completed Sep 8, 2016 2:11:32 PM 
+0

Где вы определяете свой insertAction? Похоже, что он не наследуется от «DBIOAction»? –

+0

'table' - это просто объект' TableQuery', 'blockHeader' - это экземпляр объекта, который хранится' table'. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 0'' –

+0

Я предполагаю, что главный вопрос заключается в том, что оператор insert может использоваться вне 'DBIO.seq', каждый тестовый пример, который они используют, использует эту функцию: https: // github.com/slick/slick/blob/898cb1871c610cea72027b266494f5bd83f770c9/slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/InsertTest.scala –

ответ

1

по умолчанию += возвращает количество затронутых строк, которые, как правило, 1. Однако, чтобы удовлетворить подпись вашей create, вам нужно будет вернуть BlockHeader. Вы можете сделать это, просто ЦЕПЬ DBIO.successful() действие, которое возвращает ваше значение «вставить»:

def create(blockHeader: BlockHeader): Future[BlockHeader] = { 
    val insertion: DBIO[BlockHeader] = (table += blockHeader).andThen(DBIO.successful(blockHeader)) 
    database.run(insertAction) 
} 

andThen выполняется только после того, как первое действие suceeded, и возвращает значение второго действия.

Не путать с returning. С returning вы можете изменить значение, которое возвращает += и ++=. Сказанное это, большинство СУБД позволяют только вернуть один, автоматически увеличиваемый первичный ключ. Например, если hash был автоматически увеличивается значение, вы можете вернуть его, как это:

val hash = (table returning table.map(_.hash)) += blockHeader 

И пойти немного дальше, вы можете также вставить это значение в вашем BlockHeader объекта с помощью into:

val blockHeaderWithHash = (table returning table.map(_.hash) into ((blockHeader, hash) => blockHeader.copy(hash = hash))) += blockHeader 
0

Вашего insertAction возвращает число строк, которые были вставлены, так что вы должны картой от этого значения и проверок если операция прошла успешно:

def create(blockHeader: BlockHeader): Future[BlockHeader] = { 
    val insertAction = (table += blockHeader).flatMap { 
    case 0 => DBIO.failed(new Exception("Failed to insert `BlockHeader` object")) 
    case _ => DBIO.successful(blockHeader) 
    } 

    db.run(insertAction) 
} 
Смежные вопросы