Parser to split dump is done

This commit is contained in:
Constantine 2025-03-15 03:42:58 +07:00
parent a23439c534
commit 1a0af88772
4 changed files with 199 additions and 4 deletions

View File

@ -10,6 +10,8 @@ repositories {
}
dependencies {
implementation("me.alllex.parsus:parsus-jvm:0.6.1")
testImplementation(kotlin("test"))
}
@ -18,4 +20,4 @@ tasks.test {
}
kotlin {
jvmToolchain(17)
}
}

View File

@ -1,5 +1,63 @@
package com.blzr
fun main() {
println("Hello World!")
}
import me.alllex.parsus.parser.*
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import kotlin.io.path.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.createDirectory
import kotlin.io.path.createParentDirectories
import kotlin.io.path.deleteIfExists
import kotlin.io.path.listDirectoryEntries
import kotlin.system.exitProcess
fun main(vararg args: String) {
val (input, output) = when (args.size) {
1 -> args[0] to "${args[0].let { if (it.endsWith(".sql")) it.dropLast(4) else it }}/out/"
2 -> args[0] to args[1]
else -> {
println("input.sql [out folder]")
exitProcess(0)
}
}
val ins = FileInputStream(input)
val text = ins.bufferedReader().readText()
val nodes = text.split(Regex("^/$", RegexOption.MULTILINE)).filter { it.isNotBlank() }
println("We have ${nodes.size} nodes")
val parser = OraDumpGrammar()
val parsed: Map<String, Ora> = nodes.associateWith { node ->
parser.parse(node).getOrElse {
println(node)
throw IllegalArgumentException(it.toString())
}
}
val outputPath = Path(output).createDirectories()
println("Create $outputPath")
outputPath.listDirectoryEntries("*.sql").forEach { entry ->
println("Delete $entry")
entry.deleteIfExists()
}
for ((text, type) in parsed) {
println("Writing ${type.fileName}")
val outputFile = File(output, type.fileName)
if (outputFile.exists()) {
throw IllegalArgumentException("File already exists $outputFile")
}
FileOutputStream(outputFile).bufferedWriter().use {
it.write(text.trim())
}
}
}

28
src/main/kotlin/Ora.kt Normal file
View File

@ -0,0 +1,28 @@
package com.blzr
sealed class Ora {
data class CreateTable(override val name: String, override val fileName: String = "table ${name.lowercase()}.sql") : Ora()
data class AlterTable(override val name: String, override val fileName: String = "table ${name.lowercase()} alter.sql") : Ora()
data class AlterTableAddConstraint(
val table: String,
override val name: String,
override val fileName: String = "table ${table.lowercase()} constraint ${name.lowercase()}.sql"
) : Ora()
data class CreateView(override val name: String, override val fileName: String = "view ${name.lowercase()}.sql") : Ora()
data class CreateIndex(override val name: String, override val fileName: String = "index ${name.lowercase()}.sql") : Ora()
data class CreateSequence(override val name: String, override val fileName: String = "sequence ${name.lowercase()}.sql") : Ora()
data class CreateFunction(override val name: String, override val fileName: String = "function ${name.lowercase()}.sql") : Ora()
data class CreateProcedure(override val name: String, override val fileName: String = "procedure ${name.lowercase()}.sql") : Ora()
data class CreateTrigger(override val name: String, override val fileName: String = "trigger ${name.lowercase()}.sql") : Ora()
data class AlterTrigger(override val name: String, override val fileName: String = "trigger ${name.lowercase()} alter.sql") :
Ora()
data class CreatePackage(override val name: String, override val fileName: String = "package ${name.lowercase()}.sql") : Ora()
data class CreatePackageBody(override val name: String, override val fileName: String = "package ${name.lowercase()} body.sql") :
Ora()
abstract val name: String
abstract val fileName: String
}

View File

@ -0,0 +1,107 @@
package com.blzr
import me.alllex.parsus.parser.Grammar
import me.alllex.parsus.parser.choose
import me.alllex.parsus.parser.map
import me.alllex.parsus.parser.maybe
import me.alllex.parsus.parser.parser
import me.alllex.parsus.parser.ref
import me.alllex.parsus.parser.times
import me.alllex.parsus.parser.unaryMinus
import me.alllex.parsus.token.literalToken
import me.alllex.parsus.token.regexToken
class OraDumpGrammar() : Grammar<Ora>(ignoreCase = true, debugMode = true) {
init {
regexToken("[\\s\\r\\n]+", ignored = true)
}
val create = literalToken("create")
val or = literalToken("or")
val replace = literalToken("replace")
val orReplace by or * replace
val force by literalToken("force")
val alter = literalToken("alter")
val table = literalToken("table")
val view = literalToken("view")
val add = literalToken("add")
val constraint = literalToken("constraint")
val editionable = literalToken("editionable")
val function = literalToken("function")
val procedure = literalToken("procedure")
val trigger = literalToken("trigger")
val pkg = literalToken("package")
val body = literalToken("body")
val unique = literalToken("unique")
val bitmap = literalToken("bitmap")
val index = literalToken("index")
val sequence = literalToken("sequence")
val quote = literalToken("\"")
val name = regexToken("\\w+")
val remaining = regexToken(Regex(".*", RegexOption.DOT_MATCHES_ALL))
val quoted by -quote * ref(::name) * -quote map { it.text }
val createTable by -create * -maybe(orReplace) * -table * quoted * -remaining map { Ora.CreateTable(it) }
val alterTable by -alter * -table * quoted * -remaining map { Ora.AlterTable(it) }
val alterTableAddConstraint by -alter * -table * quoted * -add * -constraint * quoted * -remaining map { (a,b) ->
Ora.AlterTableAddConstraint(a, b)
}
val createView by -create * -maybe(orReplace) * -maybe(force) * -maybe(editionable) * -view * quoted * -remaining map {
Ora.CreateView(
it
)
}
val createIndex by -create * -maybe(orReplace) * -maybe(unique) * -maybe(bitmap) * -index * quoted * -remaining map
{ Ora.CreateIndex(it) }
val createSequence by -create * -maybe(orReplace) * -sequence * quoted * -remaining map
{ Ora.CreateSequence(it) }
val createFunction by -create * -maybe(orReplace) * -maybe(editionable) * -function * quoted * -remaining map
{ Ora.CreateFunction(it) }
val createProcedure by -create * -maybe(orReplace) * -maybe(editionable) * -procedure * quoted * -remaining map
{ Ora.CreateProcedure(it) }
val createTrigger by -create * -maybe(orReplace) * -maybe(editionable) * -trigger * quoted * -remaining map
{ Ora.CreateTrigger(it) }
val alterTrigger by -alter * -trigger * quoted * -remaining map
{ Ora.AlterTrigger(it) }
val createPackage by -create * -maybe(orReplace) * -maybe(editionable) * -pkg * quoted * -remaining map {
Ora.CreatePackage(
it
)
}
val createPackageBody by -create * -maybe(orReplace) * -maybe(editionable) * -pkg * -body * quoted * -remaining map {
Ora.CreatePackageBody(
it
)
}
override val root by parser {
choose(
createTable,
alterTableAddConstraint,
alterTable,
createView,
createIndex,
createSequence,
createFunction,
createProcedure,
createTrigger,
alterTrigger,
createPackage,
createPackageBody,
)
}
}