@ -2,6 +2,8 @@
@@ -2,6 +2,8 @@
package de.srsoftware.umbrella.stock ;
import static de.srsoftware.tools.Optionals.nullIfEmpty ;
import static de.srsoftware.tools.jdbc.Condition.equal ;
import static de.srsoftware.tools.jdbc.Condition.isNull ;
import static de.srsoftware.tools.jdbc.Query.* ;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL ;
import static de.srsoftware.umbrella.core.Constants.* ;
@ -11,11 +13,13 @@ import static java.lang.System.Logger.Level.ERROR;
@@ -11,11 +13,13 @@ import static java.lang.System.Logger.Level.ERROR;
import static java.lang.System.Logger.Level.WARNING ;
import static java.text.MessageFormat.format ;
import de.srsoftware.tools.Tuple ;
import de.srsoftware.umbrella.core.BaseDb ;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException ;
import de.srsoftware.umbrella.core.model.Company ;
import de.srsoftware.umbrella.core.model.Item ;
import de.srsoftware.umbrella.core.model.Location ;
import de.srsoftware.umbrella.core.model.UmbrellaUser ;
import java.sql.Connection ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
@ -61,7 +65,6 @@ public class SqliteDb extends BaseDb implements StockDb {
@@ -61,7 +65,6 @@ public class SqliteDb extends BaseDb implements StockDb {
dropTokenTable ( ) ;
case 2 :
transformTables ( ) ;
replaceLocationsTable ( ) ;
}
return setCurrentVersion ( 3 ) ;
}
@ -78,6 +81,12 @@ public class SqliteDb extends BaseDb implements StockDb {
@@ -78,6 +81,12 @@ public class SqliteDb extends BaseDb implements StockDb {
db . prepareStatement ( sql ) . execute ( ) ;
}
private void createIntermediatePropsTable ( ) throws SQLException { // create intermediate table
var sql = "CREATE TABLE IF NOT EXISTS item_props_temp ( {0} LONG NOT NULL, {1} LONG NOT NULL, {2} LONG NOT NULL, {3} VARCHAR(255) NOT NULL, PRIMARY KEY({0}, {1}, {2}))" ;
sql = format ( sql , OWNER , ITEM_ID , PROPERTY_ID , VALUE ) ;
db . prepareStatement ( sql ) . execute ( ) ;
}
private void createItemsTable ( ) {
try {
var sql = "CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255) NOT NULL, {3} TEXT, {4} VARCHAR(255))" ;
@ -136,16 +145,44 @@ public class SqliteDb extends BaseDb implements StockDb {
@@ -136,16 +145,44 @@ public class SqliteDb extends BaseDb implements StockDb {
return List . of ( ) ;
}
@Override
public Collection < Location > listCompanyLocations ( Company company ) {
try {
var rs = select ( ALL ) . from ( TABLE_LOCATIONS ) . where ( OWNER , equal ( - company . id ( ) ) ) . where ( PARENT_LOCATION_ID , isNull ( ) ) . exec ( db ) ;
var list = new ArrayList < Location > ( ) ;
while ( rs . next ( ) ) list . add ( Location . of ( rs ) ) ;
rs . close ( ) ;
return list ;
} catch ( SQLException e ) {
throw databaseException ( "Failed to load locations for user {0}" , company . name ( ) ) ;
}
}
@Override
public Collection < Location > listUserLocations ( UmbrellaUser user ) {
try {
var rs = select ( ALL ) . from ( TABLE_LOCATIONS ) . where ( OWNER , equal ( user . id ( ) ) ) . where ( PARENT_LOCATION_ID , isNull ( ) ) . exec ( db ) ;
var list = new ArrayList < Location > ( ) ;
while ( rs . next ( ) ) list . add ( Location . of ( rs ) ) ;
rs . close ( ) ;
return list ;
} catch ( SQLException e ) {
throw databaseException ( "Failed to load locations for user {0}" , user . name ( ) ) ;
}
}
private void transformTables ( ) {
try {
db . setAutoCommit ( false ) ;
createIntermediateLocationTable ( ) ;
createIntermediateItemsTable ( ) ;
createIntermediatePropsTable ( ) ;
var oldLocationIdsToNew = transformLocations ( ) ;
transformItems ( oldLocationIdsToNew ) ;
transformProperties ( ) ;
replaceLocationsTable ( ) ;
replaceItemsTable ( ) ;
replaceItemPropsTable ( ) ;
db . setAutoCommit ( true ) ;
} catch ( Exception e ) {
try {
@ -157,15 +194,19 @@ public class SqliteDb extends BaseDb implements StockDb {
@@ -157,15 +194,19 @@ public class SqliteDb extends BaseDb implements StockDb {
}
}
private void replaceLocationsTable ( ) {
try {
db . setAutoCommit ( false ) ;
private void replaceItemsTable ( ) throws SQLException {
db . prepareStatement ( format ( "DROP TABLE {0}" , TABLE_ITEMS ) ) . execute ( ) ;
db . prepareStatement ( format ( "ALTER TABLE {0} RENAME TO {1}" , "items_temp" , TABLE_ITEMS ) ) . execute ( ) ;
}
private void replaceItemPropsTable ( ) throws SQLException {
db . prepareStatement ( format ( "DROP TABLE {0}" , TABLE_ITEM_PROPERTIES ) ) . execute ( ) ;
db . prepareStatement ( format ( "ALTER TABLE {0} RENAME TO {1}" , "item_props_temp" , TABLE_ITEM_PROPERTIES ) ) . execute ( ) ;
}
private void replaceLocationsTable ( ) throws SQLException {
db . prepareStatement ( format ( "DROP TABLE {0}" , TABLE_LOCATIONS ) ) . execute ( ) ;
db . prepareStatement ( format ( "ALTER TABLE {0} RENAME TO {1}" , "locations_temp" , TABLE_LOCATIONS ) ) . execute ( ) ;
db . setAutoCommit ( true ) ;
} catch ( SQLException e ) {
throw databaseException ( "Failed to replace locations table!" ) ;
}
}
private void transformItems ( Map < String , Long > oldLocationIdsToNew ) throws SQLException {
@ -224,4 +265,28 @@ public class SqliteDb extends BaseDb implements StockDb {
@@ -224,4 +265,28 @@ public class SqliteDb extends BaseDb implements StockDb {
return oldToNew ;
}
private void transformProperties ( ) throws SQLException {
var rs = select ( ALL ) . from ( TABLE_ITEM_PROPERTIES ) . exec ( db ) ;
var insert = insertInto ( "item_props_temp" , OWNER , ITEM_ID , PROPERTY_ID , VALUE ) ;
while ( rs . next ( ) ) {
var oldItemId = rs . getString ( ITEM_ID ) ;
var parts = oldItemId . split ( ":" ) ;
var owner = 0L ;
var itemId = 0L ;
try {
owner = Long . parseLong ( parts [ 1 ] ) ;
itemId = Long . parseLong ( parts [ 2 ] ) ;
} catch ( NumberFormatException e ) {
throw databaseException ( "Expected item id to be of format ss:dd:dd, but encountered \"{0}\"" , oldItemId ) ;
}
var ownerIsCompany = switch ( parts [ 0 ] ) {
case "company" - > true ;
case "user" - > false ;
case null , default - > throw databaseException ( "Expected item id to start with 'company:' or 'user:', encountered \"{0}\"" , oldItemId ) ;
} ;
insert . values ( ownerIsCompany ? - owner : owner , itemId , rs . getLong ( PROPERTY_ID ) , rs . getString ( VALUE ) ) ;
}
rs . close ( ) ;
insert . execute ( db ) . close ( ) ;
}
}