@ -1,18 +1,26 @@
/* © SRSoftware 2025 */
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.stock ;
package de.srsoftware.umbrella.stock ;
import static de.srsoftware.tools.Optionals.nullIfEmpty ;
import static de.srsoftware.tools.jdbc.Query.select ;
import static de.srsoftware.tools.jdbc.Query.update ;
import static de.srsoftware.umbrella.core.Constants.* ;
import static de.srsoftware.umbrella.core.Constants.* ;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException ;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException ;
import static de.srsoftware.umbrella.stock.Constants.* ;
import static de.srsoftware.umbrella.stock.Constants.* ;
import static java.lang.System.Logger.Level.ERROR ;
import static java.text.MessageFormat.format ;
import static java.text.MessageFormat.format ;
import de.srsoftware.tools.Tuple ;
import de.srsoftware.umbrella.core.BaseDb ;
import de.srsoftware.umbrella.core.BaseDb ;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException ;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException ;
import de.srsoftware.umbrella.core.model.Hash ;
import de.srsoftware.umbrella.core.model.Item ;
import de.srsoftware.umbrella.core.model.Item ;
import de.srsoftware.umbrella.core.model.Location ;
import de.srsoftware.umbrella.core.model.Location ;
import java.sql.Connection ;
import java.sql.Connection ;
import java.sql.SQLException ;
import java.sql.SQLException ;
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Collection ;
import java.util.HashMap ;
import java.util.List ;
import java.util.List ;
public class SqliteDb extends BaseDb implements StockDb {
public class SqliteDb extends BaseDb implements StockDb {
@ -29,8 +37,11 @@ public class SqliteDb extends BaseDb implements StockDb {
createItemsTable ( ) ;
createItemsTable ( ) ;
createPropertiesTable ( ) ;
createPropertiesTable ( ) ;
createItemPropsTable ( ) ;
createItemPropsTable ( ) ;
case 1 :
transformLocationsTable ( ) ;
}
}
return setCurrentVersion ( 1 ) ;
return setCurrentVersion ( 2 ) ;
}
}
private void createItemsTable ( ) {
private void createItemsTable ( ) {
@ -83,5 +94,64 @@ public class SqliteDb extends BaseDb implements StockDb {
return List . of ( ) ;
return List . of ( ) ;
}
}
private void transformLocationsTable ( ) {
try {
db . setAutoCommit ( false ) ;
var sql = "ALTER TABLE {0} ADD COLUMN {1} LONG NOT NULL DEFAULT ``" ;
sql = format ( sql , TABLE_LOCATIONS , OWNER ) ;
db . prepareStatement ( sql ) . execute ( ) ;
var rs = select ( ID , LOCATION_ID ) . from ( TABLE_LOCATIONS ) . exec ( db ) ;
var queue = new ArrayList < Tuple < String , String > > ( ) ;
var map = new HashMap < String , Long > ( ) ; // map from old ids to new numeric ids
var ids = new HashMap < Long , Long > ( ) ; // map from owner to last inserted id
while ( rs . next ( ) ) queue . add ( Tuple . of ( rs . getString ( ID ) , nullIfEmpty ( rs . getString ( LOCATION_ID ) ) ) ) ;
rs . close ( ) ;
var query = update ( TABLE_LOCATIONS ) . set ( ID , LOCATION_ID , OWNER ) . prepare ( db ) ;
while ( ! queue . isEmpty ( ) ) {
var entry = queue . removeFirst ( ) ;
var oldId = entry . a ;
var oldLoc = nullIfEmpty ( entry . b ) ;
if ( oldLoc ! = null & & ! map . containsKey ( oldLoc ) ) {
queue . add ( entry ) ;
continue ;
}
var parts = oldId . split ( ":" ) ;
if ( parts . length ! = 3 ) throw new IllegalArgumentException ( format ( "Expected 'xxx:dd:yy', got {0}" , oldId ) ) ;
long ownerId ;
try {
ownerId = Long . parseLong ( parts [ 1 ] ) ;
} catch ( NumberFormatException nfe ) {
throw new IllegalArgumentException ( format ( "Expected 'xxx:dd:yy', got {0}" , oldId ) ) ;
}
switch ( parts [ 0 ] ) {
case "company" :
ownerId = - ownerId ;
break ;
case "user" :
break ;
default :
throw new IllegalArgumentException ( format ( "Expected 'company:dd:dd' or 'user:dd:dd', got {0}" , oldId ) ) ;
}
Long location = null ;
if ( oldLoc ! = null ) {
var expected = String . join ( ":" , parts [ 0 ] , parts [ 1 ] , "" ) ;
if ( ! oldLoc . startsWith ( expected ) ) throw new IllegalArgumentException ( format ( "Expected location_id to start with {1}, got {0}" , oldId , expected ) ) ;
location = Long . parseLong ( oldLoc . substring ( expected . length ( ) ) ) ;
}
var itemId = ids . get ( ownerId ) ;
if ( itemId = = null ) itemId = 1L ;
ids . put ( ownerId , itemId + 1 ) ;
query . apply ( itemId , location , ownerId ) ;
map . put ( oldId , itemId ) ;
}
db . setAutoCommit ( true ) ;
} catch ( Exception e ) {
try {
db . rollback ( ) ;
} catch ( SQLException ignored ) {
}
LOG . log ( ERROR , "Failed to transform {0} table!" , TABLE_LOCATIONS , e ) ;
throw databaseException ( "Failed to transform {0} table!" , TABLE_LOCATIONS ) ;
}
}
}
}