Skip to content

Commit

Permalink
copy the database and create a new user
Browse files Browse the repository at this point in the history
  • Loading branch information
ymll58 committed Nov 9, 2023
1 parent d695751 commit bbaef5f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ abstract case class DBOperationsService(dbName: String, username: String, queryT
def initDB(client: JDBCClient, query: String): Future[ResultSet] = {
queryFutureWithTimeout(client, query)
}
def copyDatabase(targetClient: JDBCClient, targetDBName: String): Future[ResultSet]

def createUserWithAccess(targetClient: JDBCClient, targetDBName: String): Future[String]

def createUserWithWriteAccess(client: JDBCClient, skipUserCreation: Boolean = false): Future[String]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,19 @@ class PsqlOperationsService(override val dbName: String, override val username:

client.queryFuture(s"$tables $constrains $views $routines $triggers")
}
override def copyDatabase(targetClient: JDBCClient, targetDBName: String): Future[ResultSet] = {
val copyDBQuery = s"CREATE DATABASE $targetDBName WITH TEMPLATE $dbName"
targetClient.queryFuture(copyDBQuery)
}

override def createUserWithAccess(targetClient: JDBCClient, targetDBName: String): Future[String] = {
val password = generateUserPassword()
val userCreateQuery = s"CREATE USER $username WITH PASSWORD '$password';"
val permissionsQuery = s"GRANT ALL PRIVILEGES ON DATABASE $targetDBName TO $username;"

for {
_ <- targetClient.queryFuture(userCreateQuery)
_ <- targetClient.queryFuture(permissionsQuery)
} yield s"postgresql://$username:$password@<target-host>/$targetDBName"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ class SQLPlaygroundService(val sqlRunArgs: SqlPlaygroundRunArgs, val con: Playgr
private def initDBOperations(): DBOperationsService = {
// Currently only PostgresSql is Supported
if (!isPsql) throw new Error("Invalid DBType. Currently only Psql is Supported")

val dbName = s"playground_db_${sqlRunArgs.database.id.toString}"
val username = s"playground_user_${sqlRunArgs.user.id.toString}"
new PsqlOperationsService(dbName, username, queryTimeout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import de.thm.ii.fbs.util.Secrets.getSHAStringFromNow
import de.thm.ii.fbs.util.{DBConnections, DBTypes, RunnerException}
import io.vertx.core.json.DecodeException
import io.vertx.lang.scala.json.JsonObject
import io.vertx.scala.core.Vertx.vertx
import io.vertx.scala.ext.sql.ResultSet
import io.vertx.scala.ext.jdbc.JDBCClient

import java.sql.SQLException
import scala.concurrent.ExecutionContext.Implicits.global
Expand Down Expand Up @@ -107,6 +109,8 @@ class SQLRunnerService(val sqlRunArgs: SqlRunArgs, val solutionCon: DBConnection
private val configDbExt = s"${getSHAStringFromNow()}_c"
private val submissionDbExt = s"${getSHAStringFromNow()}_s"



private def isVariable(taskQuery: TaskQuery): Boolean =
taskQuery.order != null && taskQuery.order.equalsIgnoreCase("variable")

Expand Down Expand Up @@ -137,6 +141,30 @@ class SQLRunnerService(val sqlRunArgs: SqlRunArgs, val solutionCon: DBConnection
dbOperation
}

def copyPlaygroundDBAndCreateUser(targetDBHost: String, targetDBPort: Int, dbUser: String, dbPassword: String, originalDBName: String, targetDBName: String): Future[String] = {
// Create a client for the target database
val targetJDBCClient = JDBCClient.createNonShared(vertx, new JsonObject()
.put("url", s"jdbc:postgresql://$targetDBHost:$targetDBPort/$targetDBName")
.put("user", dbUser)
.put("password", dbPassword)
)

// Initialize a new instance of PsqlOperationsService with the original database name, user, and password
val targetDBOperations = new PsqlOperationsService(originalDBName, dbUser, queryTimout)

// First, copy the database to the new instance
val copyDBFuture = targetDBOperations.copyDatabase(targetJDBCClient, targetDBName)

// Then, create a new user with access to the copied database
val createUserFuture = copyDBFuture.flatMap { _ =>
targetDBOperations.createUserWithAccess(targetJDBCClient, targetDBName)
}
// Return the PostgreSQL URI
createUserFuture.map { newUserAndPassword =>
s"jdbc:postgresql://$targetDBHost:$targetDBPort/$targetDBName?user=$newUserAndPassword._1&password=$newUserAndPassword._2"
}
}

private def buildName(nameExtension: String): String = s"${sqlRunArgs.submissionId}_${sqlRunArgs.runnerId}_$nameExtension"

/**
Expand Down Expand Up @@ -275,4 +303,19 @@ class SQLRunnerService(val sqlRunArgs: SqlRunArgs, val solutionCon: DBConnection

(msg, success, correctResults)
}

/** def copyPlaygroundDBAndCreateUser(targetDBHost: String, targetDBPort: Int): Future[String] = {
val targetDBName = s"${dbName}_copy"
val targetJDBCClient = JDBCClient.createNonShared(vertx, new JsonObject()
.put("url", s"jdbc:postgresql://$targetDBHost:$targetDBPort/")
.put("user", username)
.put("password", password)
)
for {
_ <- copyDatabase(targetJDBCClient, targetDBName)
uri <- createUserWithAccess(targetJDBCClient, targetDBName)
} yield uri
}
**/
}

0 comments on commit bbaef5f

Please sign in to comment.