diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/controller/DatabaseController.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/controller/DatabaseController.kt new file mode 100644 index 00000000..26a86f0f --- /dev/null +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/controller/DatabaseController.kt @@ -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 { + 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") +} \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/model/data/Query.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/model/data/Query.kt index 1eca6632..e562ed24 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/model/data/Query.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/model/data/Query.kt @@ -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, val data: List) { +class Query(name: String, query: String, val columns: List, val data: List) { val nameProperty = name.toProperty() val name by nameProperty + + val queryProperty = query.toProperty() + val query by queryProperty } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/DatabaseService.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/DatabaseService.kt index 5319db08..9b892a3c 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/DatabaseService.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/DatabaseService.kt @@ -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 run(op: Connection.() -> T): T? + + fun execute(statement: String, name: String = ""): Query? } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/H2DatabaseService.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/H2DatabaseService.kt index 6034cf27..1c83254f 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/H2DatabaseService.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/service/H2DatabaseService.kt @@ -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 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() + + for (i in 1..metadata.columnCount) { + columns += metadata.getColumnLabel(i) + } + + val data = mutableListOf() + while (results.next()) { + val record = mutableMapOf() + + 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 + } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/list/TablesListView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/list/TablesListView.kt index 89417e34..78249cff 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/list/TablesListView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/list/TablesListView.kt @@ -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() - - for (i in 1..metadata.columnCount) { - columns += metadata.getColumnLabel(i) - } - - val data = mutableListOf() - while (results.next()) { - val record = mutableMapOf() - - 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) } } \ No newline at end of file diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/query/QueryResultView.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/query/QueryResultView.kt index f957d6dc..a9c8fd82 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/query/QueryResultView.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/view/query/QueryResultView.kt @@ -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() - private val table = tableview { - } + private val table = tableview() 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 diff --git a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/viewmodel/QueryVM.kt b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/viewmodel/QueryVM.kt index 7b9a0a73..41d0a10a 100644 --- a/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/viewmodel/QueryVM.kt +++ b/editor/src/main/kotlin/com/bartlomiejpluta/base/editor/database/viewmodel/QueryVM.kt @@ -7,4 +7,7 @@ import tornadofx.getValue class QueryVM(query: Query) : ItemViewModel(query) { val nameProperty = bind(Query::nameProperty) val name by nameProperty + + val queryProperty = bind(Query::queryProperty) + val query by queryProperty } \ No newline at end of file