Skip to content

Commit

Permalink
chore: upgrade h2 database
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Dec 6, 2023
1 parent c1f98d2 commit 5ff40a2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ lazy val metals = project
"org.jboss.xnio" % "xnio-nio" % "3.8.12.Final",
// for persistent data like "dismissed notification"
"org.flywaydb" % "flyway-core" % "9.22.3",
"com.h2database" % "h2" % "2.1.214",
"com.h2database" % "h2" % "2.2.224",
// for BSP
"org.scala-sbt.ipcsocket" % "ipcsocket" % "1.6.2",
"ch.epfl.scala" % "bsp4j" % V.bsp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ class MetalsLspService(
cancelable
}

private def loadFingerPrints(): Unit = {
private def loadFingerPrints(): Future[Unit] = Future {
// load fingerprints from last execution
fingerprints.addAll(tables.fingerprints.load())
}
Expand Down Expand Up @@ -908,11 +908,10 @@ class MetalsLspService(
val isInitialized = new AtomicBoolean(false)

def initialized(): Future[Unit] = {
loadFingerPrints()
registerNiceToHaveFilePatterns()
tables.connect()

for {
_ <- loadFingerPrints()
_ <- maybeSetupScalaCli()
_ <-
Future
Expand Down
50 changes: 49 additions & 1 deletion metals/src/main/scala/scala/meta/internal/metals/Tables.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package scala.meta.internal.metals
import java.nio.file.Files
import java.sql.Connection
import java.sql.DriverManager
import java.sql.SQLException
import java.util.Properties
import java.util.concurrent.atomic.AtomicReference

import scala.util.control.NonFatal
Expand All @@ -14,6 +16,9 @@ import scala.meta.io.AbsolutePath

import org.flywaydb.core.Flyway
import org.flywaydb.core.api.FlywayException
import org.h2.mvstore.DataUtils
import org.h2.mvstore.MVStoreException
import org.h2.tools.Upgrade

final class Tables(
workspace: AbsolutePath,
Expand Down Expand Up @@ -41,6 +46,8 @@ final class Tables(
private val ref: AtomicReference[ConnectionState] =
new AtomicReference(ConnectionState.Empty)

private val user = "sa"

def connect(): Connection = {
ref.get() match {
case empty @ ConnectionState.Empty =>
Expand Down Expand Up @@ -138,11 +145,11 @@ final class Tables(
System.getProperty("h2.bindAddress", "127.0.0.1"),
)
val url = s"jdbc:h2:file:$dbfile$autoServer"
upgradeIfNeeded(url)
tryUrl(url)
}

private def tryUrl(url: String): Connection = {
val user = "sa"
val flyway = Flyway.configure.dataSource(url, user, null).load()
migrateOrRestart(flyway)
DriverManager.getConnection(url, user, null)
Expand All @@ -161,6 +168,47 @@ final class Tables(
}
}

/**
* Between h2 "2.1.x" and "2.2.x" write/read formats in MVStore changed
* (https://github.com/h2database/h2database/pull/3834)
*/
private def upgradeIfNeeded(url: String): Unit = {
val oldVersion = 214
val formatVersionChangedMessage =
"The write format 2 is smaller than the supported format 3"
try {
DriverManager.getConnection(url, user, null)
} catch {
case e: SQLException if e.getErrorCode() == 90048 =>
e.getCause() match {
case e: MVStoreException
if e.getErrorCode() == DataUtils.ERROR_UNSUPPORTED_FORMAT &&
e.getMessage().startsWith(formatVersionChangedMessage) =>
val info: Properties = new Properties()
info.put("user", user)
try {
val didUpgrade = Upgrade.upgrade(url, info, oldVersion)
if (didUpgrade) scribe.info(s"Upgraded H2 database.")
else deleteDatabase()
} catch {
case NonFatal(_) => deleteDatabase()
}

case e => throw e
}
}
}

private def deleteDatabase() = {
val dbFile = workspace.resolve(".metals").resolve("metals.mv.db")
if (dbFile.exists) {
scribe.warn(
s"Deleting old database, due to failed database upgrade. Non-default build tool and build server choices will be lost."
)
dbFile.delete()
}
}

def cleanAll(): Unit = {
try {
jarSymbols.clearAll()
Expand Down

0 comments on commit 5ff40a2

Please sign in to comment.