[Editor] Enable refreshing Queries
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
package com.bartlomiejpluta.base.editor.database.controller
|
||||
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.Query
|
||||
import com.bartlomiejpluta.base.editor.database.service.DatabaseService
|
||||
import org.springframework.stereotype.Component
|
||||
import tornadofx.Controller
|
||||
import tornadofx.error
|
||||
import java.sql.Connection
|
||||
import java.sql.SQLException
|
||||
|
||||
@Component
|
||||
class DatabaseController : Controller() {
|
||||
private val databaseService: DatabaseService by di()
|
||||
|
||||
fun execute(statement: String, name: String = ""): Query? = try {
|
||||
databaseService.execute(statement, name)
|
||||
} catch (e: SQLException) {
|
||||
sqlErrorAlert(e)
|
||||
null
|
||||
}
|
||||
|
||||
fun execute(op: Connection.() -> Unit) {
|
||||
databaseService.run<Unit> {
|
||||
try {
|
||||
op(this)
|
||||
} catch (e: SQLException) {
|
||||
sqlErrorAlert(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sqlErrorAlert(e: SQLException) =
|
||||
error("SQL Error ${e.sqlState}", e.joinToString("\n") { e.message ?: "" }, title = "SQL Error")
|
||||
}
|
||||
@@ -3,7 +3,10 @@ package com.bartlomiejpluta.base.editor.database.model.data
|
||||
import tornadofx.getValue
|
||||
import tornadofx.toProperty
|
||||
|
||||
class Query(name: String, val columns: List<String>, val data: List<DataRecord>) {
|
||||
class Query(name: String, query: String, val columns: List<String>, val data: List<DataRecord>) {
|
||||
val nameProperty = name.toProperty()
|
||||
val name by nameProperty
|
||||
|
||||
val queryProperty = query.toProperty()
|
||||
val query by queryProperty
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.bartlomiejpluta.base.editor.database.service
|
||||
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.Query
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.SchemaDatabase
|
||||
import java.sql.Connection
|
||||
|
||||
interface DatabaseService {
|
||||
val database: SchemaDatabase
|
||||
fun run(op: Connection.() -> Unit)
|
||||
|
||||
fun <T> run(op: Connection.() -> T): T?
|
||||
|
||||
fun execute(statement: String, name: String = ""): Query?
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.bartlomiejpluta.base.editor.database.service
|
||||
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataField
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataRecord
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.Query
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.ColumnType
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.SchemaDatabase
|
||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||
@@ -42,9 +45,38 @@ class H2DatabaseService : DatabaseService {
|
||||
@Autowired
|
||||
private lateinit var projectContext: ProjectContext
|
||||
|
||||
override fun run(op: Connection.() -> Unit) {
|
||||
projectContext.project?.database?.connection?.use(op)
|
||||
override fun <T> run(op: Connection.() -> T): T? {
|
||||
return projectContext.project?.database?.connection?.use(op)
|
||||
}
|
||||
|
||||
private fun parseType(type: String) = ColumnType.valueOf(type.replace(" ", "_").substringBefore("("))
|
||||
|
||||
override fun execute(statement: String, name: String): Query? = run {
|
||||
val stmt = prepareStatement(statement).apply { execute() }
|
||||
val results = stmt.resultSet
|
||||
val metadata = stmt.metaData
|
||||
|
||||
if (results != null && metadata != null) {
|
||||
val columns = mutableListOf<String>()
|
||||
|
||||
for (i in 1..metadata.columnCount) {
|
||||
columns += metadata.getColumnLabel(i)
|
||||
}
|
||||
|
||||
val data = mutableListOf<DataRecord>()
|
||||
while (results.next()) {
|
||||
val record = mutableMapOf<String, DataField>()
|
||||
|
||||
for (i in 1..metadata.columnCount) {
|
||||
record[metadata.getColumnLabel(i)] = DataField(results.getObject(i).toString())
|
||||
}
|
||||
|
||||
data += DataRecord(record)
|
||||
}
|
||||
|
||||
return@run Query(name, statement, columns, data)
|
||||
}
|
||||
|
||||
return@run null
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.bartlomiejpluta.base.editor.database.view.list
|
||||
|
||||
import com.bartlomiejpluta.base.editor.database.component.SQLElementCell
|
||||
import com.bartlomiejpluta.base.editor.database.controller.DatabaseController
|
||||
import com.bartlomiejpluta.base.editor.database.model.*
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataField
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataRecord
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.Query
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.Schema
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.SchemaDatabase
|
||||
import com.bartlomiejpluta.base.editor.database.model.schema.SchemaTable
|
||||
@@ -15,13 +13,12 @@ import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||
import javafx.scene.control.TreeItem
|
||||
import org.kordamp.ikonli.javafx.FontIcon
|
||||
import tornadofx.*
|
||||
import java.sql.Connection
|
||||
import java.sql.SQLException
|
||||
|
||||
class TablesListView : View() {
|
||||
private val mainController: MainController by di()
|
||||
private val projectContext: ProjectContext by di()
|
||||
private val databaseService: DatabaseService by di()
|
||||
private val databaseController: DatabaseController by di()
|
||||
|
||||
private var database: SchemaDatabase? = null
|
||||
|
||||
@@ -37,9 +34,9 @@ class TablesListView : View() {
|
||||
setOnMouseClicked { event ->
|
||||
val selected = selectionModel?.selectedItem?.value
|
||||
if (event.clickCount == 2 && selected is SchemaTable) {
|
||||
onConnection {
|
||||
executeScript(selected.name, "SELECT * FROM ${selected.name}", this)
|
||||
}
|
||||
databaseController
|
||||
.execute("SELECT * FROM ${selected.name}", selected.name)
|
||||
?.let(mainController::openQuery)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +54,10 @@ class TablesListView : View() {
|
||||
val name = "Script ${++index}"
|
||||
mainController.openScript(
|
||||
fsNode = InMemoryStringFileNode(name, "sql", ""),
|
||||
execute = { code -> onConnection { executeScript(name, code, this) } },
|
||||
execute = { code ->
|
||||
databaseController.execute(code, name)?.let(mainController::openQuery)
|
||||
refresh()
|
||||
},
|
||||
saveable = false
|
||||
)
|
||||
}
|
||||
@@ -84,51 +84,12 @@ class TablesListView : View() {
|
||||
treeView.root.expandTo(1)
|
||||
}
|
||||
|
||||
private fun onConnection(op: Connection.() -> Unit) {
|
||||
databaseService.run {
|
||||
try {
|
||||
op(this)
|
||||
} catch (e: SQLException) {
|
||||
error("SQL Error ${e.sqlState}", e.joinToString("\n") { e.message ?: "" }, title = "SQL Error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeScript(name: String, sql: String, conn: Connection) {
|
||||
val stmt = conn.prepareStatement(sql).apply { execute() }
|
||||
val results = stmt.resultSet
|
||||
val metadata = stmt.metaData
|
||||
|
||||
if (results != null && metadata != null) {
|
||||
val columns = mutableListOf<String>()
|
||||
|
||||
for (i in 1..metadata.columnCount) {
|
||||
columns += metadata.getColumnLabel(i)
|
||||
}
|
||||
|
||||
val data = mutableListOf<DataRecord>()
|
||||
while (results.next()) {
|
||||
val record = mutableMapOf<String, DataField>()
|
||||
|
||||
for (i in 1..metadata.columnCount) {
|
||||
record[metadata.getColumnLabel(i)] = DataField(results.getObject(i).toString())
|
||||
}
|
||||
|
||||
data += DataRecord(record)
|
||||
}
|
||||
|
||||
mainController.openQuery(Query(name, columns, data))
|
||||
}
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
private fun renameElement(element: Schema, newName: String): Schema {
|
||||
onConnection { element.rename(this, newName) }
|
||||
databaseController.execute { element.rename(this, newName) }
|
||||
return element
|
||||
}
|
||||
|
||||
private fun deleteElement(element: Schema) {
|
||||
onConnection(element::delete)
|
||||
databaseController.execute(element::delete)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.bartlomiejpluta.base.editor.database.view.query
|
||||
|
||||
import com.bartlomiejpluta.base.editor.database.component.QueryFieldCell
|
||||
import com.bartlomiejpluta.base.editor.database.controller.DatabaseController
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataField
|
||||
import com.bartlomiejpluta.base.editor.database.model.data.DataRecord
|
||||
import com.bartlomiejpluta.base.editor.database.viewmodel.QueryVM
|
||||
import javafx.scene.control.TableColumn
|
||||
import org.kordamp.ikonli.javafx.FontIcon
|
||||
import tornadofx.*
|
||||
|
||||
class QueryResultView : View() {
|
||||
private val databaseController: DatabaseController by di()
|
||||
private val queryVM = find<QueryVM>()
|
||||
|
||||
private val table = tableview<DataRecord> {
|
||||
}
|
||||
private val table = tableview<DataRecord>()
|
||||
|
||||
init {
|
||||
queryVM.itemProperty.addListener { _, _, _ -> refreshData() }
|
||||
@@ -38,7 +40,11 @@ class QueryResultView : View() {
|
||||
|
||||
override val root = borderpane {
|
||||
top = toolbar {
|
||||
|
||||
button(graphic = FontIcon("fa-refresh")) {
|
||||
action {
|
||||
databaseController.execute(queryVM.query, queryVM.name)?.let { queryVM.item = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
center = table
|
||||
|
||||
@@ -7,4 +7,7 @@ import tornadofx.getValue
|
||||
class QueryVM(query: Query) : ItemViewModel<Query>(query) {
|
||||
val nameProperty = bind(Query::nameProperty)
|
||||
val name by nameProperty
|
||||
|
||||
val queryProperty = bind(Query::queryProperty)
|
||||
val query by queryProperty
|
||||
}
|
||||
Reference in New Issue
Block a user