Skip to content

Commit

Permalink
Merge pull request #2 from Paulanerus/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Paulanerus authored Dec 12, 2024
2 parents e6990ca + 74ae184 commit b421938
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 34 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ jobs:
- name: Create Release
run: gh release create v${{ steps.extract_version.outputs.ver }} --generate-notes

build-api:
needs: create-release

runs-on: ubuntu-latest

env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ needs.create-release.outputs.version }}

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Java
uses: actions/setup-java@v4.5.0
with:
java-version: '21'
distribution: 'corretto'
cache: 'gradle'

- name: Extract API Version
run: echo "API_VERSION=$(grep 'api.version=' gradle.properties | cut -d '=' -f2)" >> $GITHUB_ENV

- name: Build API
run: ./gradlew :api:build

- name: Upload API
run: gh release upload v${{ env.VERSION }} api/build/libs/api-${{ API_VERSION }}.jar --clobber

build:
needs: create-release

Expand Down
2 changes: 2 additions & 0 deletions api/src/main/kotlin/dev/paulee/api/data/IDataService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ interface IDataService : Closeable {
fun createDataPool(dataInfo: RequiresData, path: Path): Boolean

fun getPage(query: String, pageCount: Int = -1): List<Map<String, String>>

fun getPageCount(query: String): Long
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ interface IStorageProvider : Closeable {
offset: Int = 0,
limit: Int = Int.MAX_VALUE
): List<Map<String, String>>

fun count(
name: String,
ids: Set<Long> = emptySet<Long>(),
whereClause: List<String> = emptyList<String>()
): Long
}
4 changes: 2 additions & 2 deletions api/src/main/kotlin/dev/paulee/api/plugin/IPluginService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import java.nio.file.Path

interface IPluginService {

fun loadFromDirectory(path: Path) : Int
fun loadFromDirectory(path: Path): Int

fun loadPlugin(path: Path) : Boolean
fun loadPlugin(path: Path, init: Boolean = false): Boolean

fun getPluginMetadata(plugin: IPlugin): PluginMetadata?

Expand Down
11 changes: 10 additions & 1 deletion core/src/main/kotlin/dev/paulee/core/data/DataServiceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import dev.paulee.core.data.io.BufferedCSVReader
import dev.paulee.core.data.search.IndexSearchServiceImpl
import java.nio.file.Path
import kotlin.io.path.exists
import kotlin.math.ceil
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.primaryConstructor

class DataServiceImpl(private val storageProvider: IStorageProvider) : IDataService {

private val searchService: IndexSearchService = IndexSearchServiceImpl()

private val pageSize = 2
private val pageSize = 50

private var currentPage = 0

Expand Down Expand Up @@ -101,6 +102,14 @@ class DataServiceImpl(private val storageProvider: IStorageProvider) : IDataServ
return entries
}

override fun getPageCount(query: String): Long {
val indexResult = this.searchService.search("", query)

val count = this.storageProvider.count("", indexResult.ids, indexResult.tokens)

return ceil(count / pageSize.toDouble()).toLong()
}

override fun close() {
this.searchService.close()
this.storageProvider.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ internal class BinaryProvider : IStorageProvider {
TODO("Not yet implemented")
}

override fun count(
name: String,
ids: Set<Long>,
whereClause: List<String>
): Long {
TODO("Not yet implemented")
}

override fun close() {
this.binaryBlob?.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,25 @@ internal class SQLiteProvider : IStorageProvider {
return db.selectAll(tableName, entries, offset = offset, limit = limit)
}

override fun count(
name: String,
ids: Set<Long>,
whereClause: List<String>
): Long {
val sourceName = name.substringBefore(".")
val tableName = name.substringAfter(".")

val db = dataSources[sourceName] ?: return 0

var entries = whereClause.filter { it.contains(":") }.groupBy { it.substringBefore(":") }
.mapValues { it.value.map { it.substringAfter(":") } }.toMutableMap()

val primaryKey = db.primaryKeyOf(tableName) ?: return 0

if (ids.isNotEmpty()) entries += primaryKey to ids.map { it.toString() }.toList()

return db.count(tableName, entries)
}

override fun close() = dataSources.values.forEach { it.close() }
}
24 changes: 19 additions & 5 deletions core/src/main/kotlin/dev/paulee/core/data/sql/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,28 @@ private class Table(val name: String, columns: List<Column>) {
}
}

fun count(connection: Connection, whereClause: String? = null): Long {
fun count(connection: Connection, whereClause: Map<String, List<String>> = emptyMap<String, List<String>>()): Long {
val query = buildString {
append("SELECT COUNT(*) FROM ")
append(name)

if (!whereClause.isNullOrEmpty()) {
append(" WHERE ")
append(whereClause)
if (whereClause.isNotEmpty()) {
val clause = whereClause.entries.joinToString(" AND ") { (column, values) ->
val columnType = getColumnType(column) ?: return@joinToString ""

val inClause = values.joinToString(
", ",
prefix = "IN (",
postfix = ")"
) { if (columnType == ColumnType.TEXT) "'$it'" else it }

"$column $inClause"
}

if (clause.isNotEmpty()) {
append(" WHERE ")
append(clause)
}
}
}

Expand Down Expand Up @@ -213,7 +227,7 @@ internal class Database(path: Path) : Closeable {
}
}

fun count(name: String, whereClause: String? = null): Long {
fun count(name: String, whereClause: Map<String, List<String>> = emptyMap<String, List<String>>()): Long {
val table = tables.find { it.name == name } ?: return -1L

return transaction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ class PluginServiceImpl : IPluginService {

@OptIn(ExperimentalPathApi::class)
override fun loadFromDirectory(path: Path): Int {
require(path.isDirectory())
if (!path.isDirectory()) return -1

return path.walk().filter { it.extension == "jar" }.mapNotNull { if (this.loadPlugin(it)) it else null }.count()
}

override fun loadPlugin(path: Path): Boolean {
require(path.extension == "jar")
override fun loadPlugin(path: Path, init: Boolean): Boolean {
if (path.extension != "jar") return false

return URLClassLoader(arrayOf(path.toUri().toURL()), this.javaClass.classLoader).use { classLoader ->
val entryPoint = this.getPluginEntryPoint(path)
Expand All @@ -38,6 +38,8 @@ class PluginServiceImpl : IPluginService {
this.collectClasses(path).filter { it != entryPoint }
.forEach { runCatching { Class.forName(it, true, classLoader) } }

if (init) plugin.init()

this.plugins.add(plugin)
} == true
}
Expand Down
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kotlin.version=2.0.20
compose.version=1.7.1
lucene.version=10.0.0

api.version=0.12.0
core.version=0.11.0
ui.version=0.6.0
app.version=1.2.0
api.version=0.14.0
core.version=0.13.0
ui.version=0.8.2
app.version=1.3.0
4 changes: 3 additions & 1 deletion src/main/kotlin/dev/paulee/Main.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package dev.paulee

import dev.paulee.core.plugin.PluginServiceImpl
import dev.paulee.ui.TextExplorerUI


fun main() {
val explorerUI = TextExplorerUI()
val explorerUI = TextExplorerUI(PluginServiceImpl())
explorerUI.start()
}
65 changes: 55 additions & 10 deletions ui/src/main/kotlin/dev/paulee/ui/TextExplorerUI.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package dev.paulee.ui

import androidx.compose.animation.*
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
Expand All @@ -18,18 +19,39 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import dev.paulee.api.plugin.IPluginService
import dev.paulee.ui.components.DiffViewerWindow
import dev.paulee.ui.components.DropDownMenu
import dev.paulee.ui.components.FileDialog
import dev.paulee.ui.components.TableView
import java.nio.file.Files
import kotlin.io.path.Path
import kotlin.io.path.copyTo
import kotlin.io.path.exists
import kotlin.io.path.extension
import kotlin.io.path.name

class TextExplorerUI {
class TextExplorerUI(private val pluginService: IPluginService) {

private val appDir = Path(System.getProperty("user.home")).resolve(".textexplorer")

private val pluginsDir = appDir.resolve("plugins")

init {
Files.createDirectories(pluginsDir)

this.pluginService.loadFromDirectory(pluginsDir)

this.pluginService.initAll()
}

@Composable
private fun content() {
var text by remember { mutableStateOf("") }
var selectedRows by remember { mutableStateOf(setOf<List<String>>()) }
var displayDiffWindow by remember { mutableStateOf(false) }
var showTable by remember { mutableStateOf(false) }
var isOpened by remember { mutableStateOf(false) }

val header = listOf(
"Column 1",
Expand All @@ -49,10 +71,29 @@ class TextExplorerUI {

DropDownMenu(
modifier = Modifier.align(Alignment.TopEnd),
items = listOf("Item 1", "Item 2", "Item 3"),
clicked = { println(it) }
items = listOf("Load Plugin"),
clicked = {
when (it) {
"Load Plugin" -> isOpened = true
}
}
)

if (isOpened) {
FileDialog { paths ->
isOpened = false

paths.filter { it.extension == "jar" }.forEach {
val path = pluginsDir.resolve(it.name)

if (path.exists()) return@forEach

it.copyTo(path)
pluginService.loadPlugin(path, true)
}
}
}

Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
Expand All @@ -75,7 +116,15 @@ class TextExplorerUI {
backgroundColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
)
),
trailingIcon = {
IconButton(onClick = {
text = ""
showTable = false
}) {
Icon(Icons.Default.Close, contentDescription = "Close")
}
}
)

IconButton(
Expand All @@ -89,11 +138,7 @@ class TextExplorerUI {

Spacer(modifier = Modifier.height(16.dp))

AnimatedVisibility(
visible = showTable,
enter = fadeIn() + slideInVertically(initialOffsetY = { it }),
exit = fadeOut() + slideOutVertically(targetOffsetY = { it })
) {
AnimatedVisibility(visible = showTable) {
Box(
modifier = Modifier.fillMaxWidth().padding(8.dp)
) {
Expand Down
33 changes: 33 additions & 0 deletions ui/src/main/kotlin/dev/paulee/ui/components/Dialog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.paulee.ui.components

import androidx.compose.runtime.Composable
import androidx.compose.ui.window.AwtWindow
import java.awt.FileDialog
import java.awt.Frame
import java.nio.file.Path

@Composable
fun FileDialog(
parent: Frame? = null,
onCloseRequest: (result: List<Path>) -> Unit
) = AwtWindow(
create = {
object : FileDialog(parent, "Choose a file", LOAD) {

init {
isMultipleMode = true
}

override fun setVisible(value: Boolean) {
super.setVisible(value)

if (value) {
val paths = files.map { it.toPath() }.toList()

onCloseRequest(paths)
}
}
}
},
dispose = FileDialog::dispose
)
Loading

0 comments on commit b421938

Please sign in to comment.