Skip to content
Snippets Groups Projects
Commit e51a20d7 authored by npedot's avatar npedot
Browse files

adds TransformerUseCase

parent cbbde2e7
No related branches found
No related tags found
No related merge requests found
Showing
with 270 additions and 175 deletions
package unibz.cs.semint.kprime package unibz.cs.semint.kprime
import unibz.cs.semint.kprime.scenario.SakilaScenario
class Starter { class Starter {
...@@ -12,7 +11,6 @@ class Starter { ...@@ -12,7 +11,6 @@ class Starter {
fun main(args:Array<String>) { fun main(args:Array<String>) {
val version = "0.1.0-SNAPSHOT" val version = "0.1.0-SNAPSHOT"
println("KPrime $version") println("KPrime $version")
SakilaScenario().run()
} }
} }
......
...@@ -6,7 +6,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement ...@@ -6,7 +6,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement
@JacksonXmlRootElement(localName = "constraint") @JacksonXmlRootElement(localName = "constraint")
class Constraint () { class Constraint () {
enum class TYPE { enum class TYPE {
FOREIGN_KEY,PRIMARY_KEY,FUNCTIONAL,INCLUSION,DISJUNCTION,COVER FOREIGN_KEY,PRIMARY_KEY,FUNCTIONAL,DOUBLE_INCLUSION,INCLUSION,DISJUNCTION,COVER
} }
@JacksonXmlProperty(isAttribute = true) @JacksonXmlProperty(isAttribute = true)
var name: String ="" var name: String =""
......
package unibz.cs.semint.kprime.scenario
import unibz.cs.semint.kprime.adapter.repository.MetaSchemaJdbcAdapter
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.DataSource
import unibz.cs.semint.kprime.domain.Database
import unibz.cs.semint.kprime.usecase.MetaSchemaReadUseCase
class SakilaScenario {
fun run() {
val sakilaMeta = readSakilaMeta()
if (sakilaMeta!=null) {
vsplitSakila(sakilaMeta)
hsplitSakila(sakilaMeta)
identifySakila(sakilaMeta)
}
}
private fun readSakilaMeta(): Database? {
val type = "psql"
val name = "sakila-source"
val driver = "org.postgresql.Driver"
val path = "jdbc:postgresql://localhost:5432/sakila"
val user = "sammy"
val pass = "pass"
val sakilaSource = DataSource(type,name,driver,path,user,pass)
val result = MetaSchemaReadUseCase().doit(sakilaSource,
"read-meta-schema sakila-source",
MetaSchemaJdbcAdapter(),
XMLSerializerJacksonAdapter())
return result.ok
}
private fun vsplitSakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
private fun hsplitSakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
private fun identifySakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
}
\ No newline at end of file
...@@ -3,6 +3,9 @@ package unibz.cs.semint.kprime.usecase ...@@ -3,6 +3,9 @@ package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.domain.ChangeSet import unibz.cs.semint.kprime.domain.ChangeSet
import unibz.cs.semint.kprime.domain.Database import unibz.cs.semint.kprime.domain.Database
/**
* Given a Databse will apply changes following a given changeSet modification.
*/
class ApplyChangeSetUseCase { class ApplyChangeSetUseCase {
fun apply(db: Database, changeset:ChangeSet):Database { fun apply(db: Database, changeset:ChangeSet):Database {
// TODO for every create* and remove* will do it on a cloned db // TODO for every create* and remove* will do it on a cloned db
......
package unibz.cs.semint.kprime.usecase package unibz.cs.semint.kprime.usecase
class VSplitApplyUseCase {}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
class HSplitApplyUseCase {
}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.domain.ChangeSet
import unibz.cs.semint.kprime.domain.Database
class HSplitDetectUseCase: TransformerUseCase {
override fun compute(db: Database): ChangeSet {
TODO("not implemented")
}
}
\ No newline at end of file
package unibz.cs.semint.kprime.scenario package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.* import unibz.cs.semint.kprime.domain.*
import unibz.cs.semint.kprime.usecase.SQLizeUseCase import unibz.cs.semint.kprime.usecase.SQLizeUseCase
import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase
class PersonHSplitScenario { class HSplitUseCase {
fun run() { fun compute(databaseMetadata: Database) {
val personMetadata = buildPersonMetadata() printDb(databaseMetadata)
hsplitPersonMetadata(personMetadata) val detected = detect(databaseMetadata)
}
private fun buildPersonMetadata(): Database {
val db = Database()
val personTable = Table()
personTable.name= "person"
val colSSN = Column("SSN", "id.SSN", "dbname.SSN")
personTable.columns.add(colSSN)
colSSN.nullable=false
val colT = Column("T", "id.T", "dbname.T")
personTable.columns.add(colT)
colT.nullable=false
val colS = Column("S", "id.S", "dbname.S")
colS.nullable=true
personTable.columns.add(colS)
db.schema.tables.add(personTable)
val primaryConstraint = Constraint()
primaryConstraint.name="primaryKey.person"
primaryConstraint.source.table="person"
primaryConstraint.source.columns.add(colSSN)
primaryConstraint.source.columns.add(colT)
primaryConstraint.type=Constraint.TYPE.PRIMARY_KEY.name
db.schema.constraints.add(primaryConstraint)
return db
}
private fun hsplitPersonMetadata(personMetadata: Database) {
printDb(personMetadata)
val detected = detect(personMetadata)
if (detected.ok!=null) { if (detected.ok!=null) {
val applied = apply(personMetadata, detected) val applied = apply(databaseMetadata, detected)
if (applied.ok!=null) { if (applied.ok!=null) {
printDb(applied.ok) printDb(applied.ok)
printSql(SQLizeUseCase().sqlize(applied.ok)) printSql(SQLizeUseCase().sqlize(applied.ok))
......
package unibz.cs.semint.kprime.usecase
class IdentifierApplyUseCase {}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
class IdentifierDetectUseCase {
}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.domain.Database
class TransformerHUseCase :TransformerUseCase {
override fun decompose(db: Database): Database {
// TODO("not implemented")
return Database()
}
override fun compose(db: Database): Database {
// TODO("not implemented")
return Database()
}
}
\ No newline at end of file
...@@ -4,5 +4,6 @@ import unibz.cs.semint.kprime.domain.ChangeSet ...@@ -4,5 +4,6 @@ import unibz.cs.semint.kprime.domain.ChangeSet
import unibz.cs.semint.kprime.domain.Database import unibz.cs.semint.kprime.domain.Database
interface TransformerUseCase { interface TransformerUseCase {
fun compute(db: Database):ChangeSet fun decompose(db: Database):Database
fun compose(db:Database): Database
} }
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.domain.Database
class TransformerVUseCase :TransformerUseCase {
override fun decompose(db: Database): Database {
val changeSet = VSplitUseCase().compute(db)
return ApplyChangeSetUseCase().apply(db,changeSet)
}
override fun compose(db: Database): Database {
val changeSet = VJoinUseCase().compute(db)
return ApplyChangeSetUseCase().apply(db,changeSet)
}
}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.domain.ChangeSet
import unibz.cs.semint.kprime.domain.Constraint
import unibz.cs.semint.kprime.domain.CreateView
import unibz.cs.semint.kprime.domain.Database
class VJoinUseCase {
fun compute(database: Database): ChangeSet {
val changeSet: ChangeSet = ChangeSet()
var tab1 = ""
var tab2 = ""
var colJoin1 = ""
var colJoin2 = ""
// if there is a double inclusion in tab1 and tab2 and a primary key on colJoin
for (const in database.schema.constraints) {
if (const.type==Constraint.TYPE.DOUBLE_INCLUSION.name) {
tab1 = const.source.table
tab2= const.target.table
colJoin1 = const.source.columns[0].name
colJoin2 = const.target.columns[0].name
break
}
}
if (tab1=="") {
return changeSet
}
val view1cols = "select * from $tab1 join $tab2 on $tab1.$colJoin1 = $tab2.$colJoin2"
val view1 = CreateView()
view1.viewName="tableJoin"
view1.text=view1cols
changeSet.createView.add(view1)
return changeSet
}
}
\ No newline at end of file
package unibz.cs.semint.kprime.usecase
class VSplitDetectUseCase {
}
\ No newline at end of file
package unibz.cs.semint.kprime.scenario package unibz.cs.semint.kprime.usecase
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.* import unibz.cs.semint.kprime.domain.*
import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase
class PersonVSplitScenario { class VSplitUseCase {
fun run(): ChangeSet { fun compute(metadataDatabase: Database): ChangeSet {
val personMetadata = buildPersonMetadata()
println(XMLSerializeUseCase(XMLSerializerJacksonAdapter()).prettyDatabase(personMetadata))
return vsplitPersonMetadata(personMetadata)
}
private fun buildPersonMetadata(): Database {
val db = Database()
val personTable = Table()
personTable.name= "person"
val colSSN = Column("SSN", "id.SSN", "dbname.SSN")
personTable.columns.add(colSSN)
colSSN.nullable=false
val colT = Column("T", "id.T", "dbname.T")
personTable.columns.add(colT)
colT.nullable=false
val colS = Column("S", "id.S", "dbname.S")
colS.nullable=true
personTable.columns.add(colS)
val colX = Column("X", "id.X", "dbname.X")
colX.nullable=true
personTable.columns.add(colX)
db.schema.key("person", mutableSetOf(colSSN))
db.schema.functional("person", mutableSetOf(colT), mutableSetOf(colS))
db.schema.tables.add(personTable)
return db
}
private fun vsplitPersonMetadata(personMetadata: Database): ChangeSet {
// check for functional dep // check for functional dep
// create changeset // create changeset
var changeSet = ChangeSet() var changeSet = ChangeSet()
// compute K // compute K
val keyCols = personMetadata.schema.key("person") val keyCols = metadataDatabase.schema.key("person")
var key = keyCols.map { x -> x.name }.toSet() var key = keyCols.map { x -> x.name }.toSet()
println("key $key") println("key $key")
// compute LHS // compute LHS
var lhsCols = personMetadata.schema.functionalLHS("person") var lhsCols = metadataDatabase.schema.functionalLHS("person")
var lhs= lhsCols.map { x -> x.name }.toSet() var lhs= lhsCols.map { x -> x.name }.toSet()
println("lhs $lhs") println("lhs $lhs")
if (lhs.isEmpty()) return changeSet if (lhs.isEmpty()) return changeSet
// compute RHS // compute RHS
val rhsCols = personMetadata.schema.functionalRHS("person") val rhsCols = metadataDatabase.schema.functionalRHS("person")
var rhs = rhsCols.map { x -> x.name }.toSet() var rhs = rhsCols.map { x -> x.name }.toSet()
println("rhs $rhs") println("rhs $rhs")
// compute Rest // compute Rest
val allCols = personMetadata.schema.table("person").columns.toSet() val allCols = metadataDatabase.schema.table("person").columns.toSet()
val all = allCols.map { x -> x.name }.toSet() val all = allCols.map { x -> x.name }.toSet()
var rest = all.minus(key).minus(lhs).minus(rhs) var rest = all.minus(key).minus(lhs).minus(rhs)
val allNotKey = all.minus(key) val allNotKey = all.minus(key)
...@@ -89,20 +53,12 @@ class PersonVSplitScenario { ...@@ -89,20 +53,12 @@ class PersonVSplitScenario {
changeSet.createConstraint.add(inclusionTab1Tab2) changeSet.createConstraint.add(inclusionTab1Tab2)
// create inclusion constraint tab2 tab1 // create inclusion constraint tab2 tab1
val inclusionTab2Tab1 = Constraint() val inclusionTab2Tab1 = Constraint()
inclusionTab2Tab1.type=Constraint.TYPE.INCLUSION.name inclusionTab2Tab1.type=Constraint.TYPE.DOUBLE_INCLUSION.name
inclusionTab2Tab1.source.table="tableName2" inclusionTab2Tab1.source.table="tableName2"
inclusionTab2Tab1.source.columns.addAll(lhsCols) inclusionTab2Tab1.source.columns.addAll(lhsCols)
inclusionTab2Tab1.target.table="tableName1" inclusionTab2Tab1.target.table="tableName1"
inclusionTab2Tab1.target.columns.addAll(lhsCols) inclusionTab2Tab1.target.columns.addAll(lhsCols)
changeSet.createConstraint.add(inclusionTab2Tab1) changeSet.createConstraint.add(inclusionTab2Tab1)
// create primary key on tab2
val primaryTab2 = Constraint()
primaryTab2.type=Constraint.TYPE.PRIMARY_KEY.name
primaryTab2.source.table="tableName2"
primaryTab2.source.columns.addAll(lhsCols)
primaryTab2.target.table="tableName2"
primaryTab2.target.columns.addAll(rhsCols)
changeSet.createConstraint.add(primaryTab2)
return changeSet return changeSet
} }
} }
\ No newline at end of file
package unibz.cs.semint.kprime.scenario package unibz.cs.semint.kprime.scenario
import org.junit.Test import org.junit.Test
import unibz.cs.semint.kprime.domain.Column
import unibz.cs.semint.kprime.domain.Constraint
import unibz.cs.semint.kprime.domain.Database
import unibz.cs.semint.kprime.domain.Table
import unibz.cs.semint.kprime.usecase.HSplitUseCase
class PersonHSplitScenarioTI { class PersonHSplitScenarioTI {
private fun buildPersonMetadata(): Database {
val db = Database()
val personTable = Table()
personTable.name= "person"
val colSSN = Column("SSN", "id.SSN", "dbname.SSN")
personTable.columns.add(colSSN)
colSSN.nullable=false
val colT = Column("T", "id.T", "dbname.T")
personTable.columns.add(colT)
colT.nullable=false
val colS = Column("S", "id.S", "dbname.S")
colS.nullable=true
personTable.columns.add(colS)
db.schema.tables.add(personTable)
val primaryConstraint = Constraint()
primaryConstraint.name="primaryKey.person"
primaryConstraint.source.table="person"
primaryConstraint.source.columns.add(colSSN)
primaryConstraint.source.columns.add(colT)
primaryConstraint.type= Constraint.TYPE.PRIMARY_KEY.name
db.schema.constraints.add(primaryConstraint)
return db
}
@Test @Test
fun test_person_hsplit_scenario() { fun test_person_hsplit_scenario() {
// given // given
val personHSplitScenario = PersonHSplitScenario() val personHSplitUseCase = HSplitUseCase()
// when // when
personHSplitScenario.run() personHSplitUseCase.compute(databaseMetadata = buildPersonMetadata())
// then // then
// prints splitted database // prints splitted database
} }
......
package unibz.cs.semint.kprime.scenario
import org.junit.Test
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.Column
import unibz.cs.semint.kprime.domain.Database
import unibz.cs.semint.kprime.domain.Table
import unibz.cs.semint.kprime.usecase.VJoinUseCase
import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase
class PersonVJoinScenarioTI {
private fun buildMetadata(): Database {
val db = Database()
val personTable1 = Table()
personTable1.name= "person1"
val colSSN = Column("SSN", "id.SSN", "dbname.SSN")
personTable1.columns.add(colSSN)
colSSN.nullable=false
val colT = Column("T", "id.T", "dbname.T")
personTable1.columns.add(colT)
colT.nullable=false
val colX = Column("X", "id.X", "dbname.X")
colX.nullable=true
personTable1.columns.add(colX)
db.schema.key("person1", mutableSetOf(colSSN))
db.schema.tables.add(personTable1)
val personTable2 = Table()
personTable2.name= "person2"
val colT2 = Column("T", "id.T", "dbname.T")
personTable2.columns.add(colT2)
colT2.nullable=false
val colS2 = Column("S", "id.S", "dbname.S")
colS2.nullable=true
personTable2.columns.add(colS2)
db.schema.key("person2", mutableSetOf(colT2))
db.schema.tables.add(personTable2)
return db
}
@Test
fun test_person_vsplit_scenario() {
// given
val personVJoinUseCase = VJoinUseCase()
// when
val changeSet = personVJoinUseCase.compute(buildMetadata())
// then
// prints changeset
println(XMLSerializeUseCase(XMLSerializerJacksonAdapter()).prettyChangeSet(changeSet))
}
}
\ No newline at end of file
...@@ -2,16 +2,51 @@ package unibz.cs.semint.kprime.scenario ...@@ -2,16 +2,51 @@ package unibz.cs.semint.kprime.scenario
import org.junit.Test import org.junit.Test
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.Column
import unibz.cs.semint.kprime.domain.Database
import unibz.cs.semint.kprime.domain.Table
import unibz.cs.semint.kprime.usecase.VSplitUseCase
import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase
class PersonVSplitScenarioTI { class PersonVSplitScenarioTI {
private fun buildPersonMetadata(): Database {
val db = Database()
val personTable = Table()
personTable.name= "person"
val colSSN = Column("SSN", "id.SSN", "dbname.SSN")
personTable.columns.add(colSSN)
colSSN.nullable=false
val colT = Column("T", "id.T", "dbname.T")
personTable.columns.add(colT)
colT.nullable=false
val colS = Column("S", "id.S", "dbname.S")
colS.nullable=true
personTable.columns.add(colS)
val colX = Column("X", "id.X", "dbname.X")
colX.nullable=true
personTable.columns.add(colX)
db.schema.key("person", mutableSetOf(colSSN))
db.schema.functional("person", mutableSetOf(colT), mutableSetOf(colS))
db.schema.tables.add(personTable)
return db
}
@Test @Test
fun test_person_vsplit_scenario() { fun test_person_vsplit_scenario() {
// given // given
val personVSplitScenario = PersonVSplitScenario() val database = buildPersonMetadata()
val personVSplitUseCase = VSplitUseCase()
// when // when
val changeSet = personVSplitScenario.run() val changeSet = personVSplitUseCase.compute(database)
// then // then
// prints changeset // prints changeset
println(XMLSerializeUseCase(XMLSerializerJacksonAdapter()).prettyChangeSet(changeSet)) println(XMLSerializeUseCase(XMLSerializerJacksonAdapter()).prettyChangeSet(changeSet))
......
package unibz.cs.semint.kprime.scenario package unibz.cs.semint.kprime.scenario
import org.junit.Test import org.junit.Test
import unibz.cs.semint.kprime.adapter.repository.MetaSchemaJdbcAdapter
import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter
import unibz.cs.semint.kprime.domain.DataSource
import unibz.cs.semint.kprime.domain.Database
import unibz.cs.semint.kprime.usecase.MetaSchemaReadUseCase
class SakilaScenarioTI { class SakilaScenarioTI {
@Test @Test
fun test_sakila_scenario() { fun test_sakila_scenario() {
// given // given
val sakilaScenario = SakilaScenario() val sakilaScenario = SakilaScenarioTI()
// when // when
sakilaScenario.run() sakilaScenario.run()
// then // then
// prints manipulated sakila database // prints manipulated sakila database
} }
fun run() {
val sakilaMeta = readSakilaMeta()
if (sakilaMeta!=null) {
vsplitSakila(sakilaMeta)
hsplitSakila(sakilaMeta)
identifySakila(sakilaMeta)
}
}
private fun readSakilaMeta(): Database? {
val type = "psql"
val name = "sakila-source"
val driver = "org.postgresql.Driver"
val path = "jdbc:postgresql://localhost:5432/sakila"
val user = "sammy"
val pass = "pass"
val sakilaSource = DataSource(type,name,driver,path,user,pass)
val result = MetaSchemaReadUseCase().doit(sakilaSource,
"read-meta-schema sakila-source",
MetaSchemaJdbcAdapter(),
XMLSerializerJacksonAdapter())
return result.ok
}
private fun vsplitSakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
private fun hsplitSakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
private fun identifySakila(db: Database) {
// if detect(db):result
// apply(db,result):db
}
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment