Диаграммы последовательностей работы коннектора Database Table#

Данный документ содержит диаграммы последовательностей (PlantUML), описывающие алгоритмы работы коннектора базы данных (Database Table Connector).

Тестирование подключения (test)#

@startuml
title Диаграмма последовательности: Тестирование подключения

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "JDBC Driver" as Driver

Framework -> Connector: test()
activate Connector
Connector -> Connection: test()
activate Connection

alt validConnectionQuery не пустой
    Connection -> Driver: createStatement()
    Driver -> Driver: execute(validConnectionQuery)
    alt query не вернул ResultSet
        Driver --> Connection: ConnectorException
    else query успешен
        Driver --> Connection: OK
    end
else validConnectionQuery пустой
    Connection -> Driver: connection.isValid(timeout)
    alt isValid = false
        Driver --> Connection: ConnectionFailedException
    else isValid = true
        Driver --> Connection: OK
    end
end

Connection --> Connector: OK
deactivate Connection
Connector --> Framework: test завершён
deactivate Connector
@enduml

Создание объекта (create)#

@startuml
title Диаграмма последовательности: Создание объекта

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt

Framework -> Connector: create(ObjectClass, attributes)
activate Connector

Connector -> Connector: buildInsertSql()
note right: Формирование SQL INSERT\nс плейсхолдерами

Connector -> Connection: prepareStatement(sql, params)
activate Connection
Connection -> Connection: getConnection().prepareStatement(sql)
Connection -> Stmt: setParams(params)

loop для каждого параметра
    Connection -> Strategy: convertToJdbc(value, columnType)
    Strategy --> Connection: JDBC значение
    Connection -> Stmt: setObject(index, value)
end

Connection --> Connector: PreparedStatement

Connector -> Stmt: executeUpdate()
activate Stmt
Stmt -> Stmt: execute INSERT
Stmt --> Connector: rows affected
deactivate Stmt

Connector -> Connector: commit()
Connector -> Connector: getGeneratedKeys() или select UID
Connector --> Framework: Uid
deactivate Connector
@enduml

Обновление объекта (update)#

@startuml
title Диаграмма последовательности: Обновление объекта

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt

Framework -> Connector: update(uid, attributes)
activate Connector

Connector -> Connector: buildUpdateSql()
note right: Формирование SQL UPDATE\nSET col1=?, col2=? WHERE key=?

Connector -> Connection: prepareStatement(sql, params)
activate Connection
Connection -> Connection: getConnection().prepareStatement(sql)

loop для каждого атрибута
    Connection -> Strategy: convertToJdbc(value, columnType)
    Strategy --> Connection: JDBC значение
    Connection -> Stmt: setObject(index, value)
end

Connection -> Stmt: setObject(lastIndex, uid)
Connection --> Connector: PreparedStatement

Connector -> Stmt: executeUpdate()
activate Stmt
Stmt -> Stmt: execute UPDATE
Stmt --> Connector: rows affected
deactivate Stmt

alt rows == 0
    Connector -> Connector: handleUnknownUid()
    Connector --> Framework: UnknownUidException
    deactivate Connector
else rows > 0
    Connector -> Connector: commit()
    Connector --> Framework: Uid
    deactivate Connector
end
@enduml

Обновление объекта (updateDelta)#

@startuml
title Диаграмма последовательности: Обновление объекта (Delta)

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt

Framework -> Connector: updateDelta(uid, attributeDeltas)
activate Connector

note right: Обработка дельт\n- valuesToReplace\n- valuesToAdd\n- valuesToRemove

Connector -> Connector: buildUpdateSqlFromDeltas(deltas)
note right: Формирование SQL UPDATE\nдля каждого изменённого атрибута

Connector -> Connection: prepareStatement(sql, params)
activate Connection

loop для каждой дельты
    loop для каждого значения
        Connection -> Strategy: convertToJdbc(value, columnType)
        Strategy --> Connection: JDBC значение
        Connection -> Stmt: setObject(index, value)
    end
end

Connection -> Stmt: setObject(lastIndex, uid)
Connection --> Connector: PreparedStatement

Connector -> Stmt: executeUpdate()
activate Stmt
Stmt -> Stmt: execute UPDATE
Stmt --> Connector: rows affected
deactivate Stmt

alt rows == 0
    Connector -> Connector: handleUnknownUid()
    Connector --> Framework: UnknownUidException
    deactivate Connector
else rows > 0
    Connector -> Connector: commit()
    Connector --> Framework: Uid
    deactivate Connector
end
@enduml

Удаление объекта (delete)#

@startuml
title Диаграмма последовательности: Удаление объекта

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt

Framework -> Connector: delete(uid, ObjectClass)
activate Connector

Connector -> Connector: buildDeleteSql()
note right: Формирование SQL DELETE\nFROM {table} WHERE {key}=?

Connector -> Connection: prepareStatement(sql, params)
activate Connection
Connection -> Connection: getConnection().prepareStatement(sql)
Connection -> Stmt: setObject(1, uid)
Connection --> Connector: PreparedStatement

Connector -> Stmt: executeUpdate()
activate Stmt
Stmt -> Stmt: execute DELETE
Stmt --> Connector: rows affected
deactivate Stmt

alt rows == 0
    Connector -> Connector: handleUnknownUid()
    Connector --> Framework: UnknownUidException
    deactivate Connector
else rows > 0
    Connector -> Connector: commit()
    Connector --> Framework: void
    deactivate Connector
end
@enduml

Поиск объектов (search/query)#

@startuml
title Диаграмма последовательности: Поиск объектов

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt
participant "ResultSet" as RS
participant "ResultsHandler" as Handler

Framework -> Connector: executeQuery(ObjectClass, filter, handler, options)
activate Connector

Connector -> Connector: buildSelectSql(filter, options)
note right: Формирование SQL SELECT\nс WHERE фильтром\nи ORDER BY

Connector -> Connection: prepareStatement(sql, params)
activate Connection
Connection -> Connection: getConnection().prepareStatement(sql)
Connection -> Stmt: setFetchSize(fetchSize)
Connection -> Stmt: setParams(params)
Connection --> Connector: PreparedStatement

Connector -> Stmt: executeQuery()
activate Stmt
Stmt --> Connector: ResultSet

loop для каждой строки
    Connector -> RS: next()
    RS --> Connector: true
    
    Connector -> Connection: getColumnValues(rs)
    activate Connection
    loop для каждой колонки
        Connection -> RS: getMetaData()
        Connection -> RS: getObject(columnName)
        Connection -> Strategy: convertFromJdbc(value, columnType)
        Strategy --> Connection: Object значение
        Connection -> Connection: добавить в Map<String, SQLParam>
    end
    Connection --> Connector: Map<String, SQLParam>
    deactivate Connection
    
    Connector -> Connector: buildConnectorObject(columnValues)
    Connector -> Handler: handle(connectorObject)
end

RS --> Connector: false (конец)
Stmt --> Connector: завершено
deactivate Stmt
deactivate Connection
Connector --> Framework: завершено
deactivate Connector
@enduml

Синхронизация (sync)#

@startuml
title Диаграмма последовательности: Синхронизация изменений

participant "IDM Framework" as Framework
participant "DatabaseTableConnector" as Connector
participant "DatabaseTableConnection" as Connection
participant "PreparedStatement" as Stmt
participant "ResultSet" as RS
participant "SyncResultsHandler" as Handler

Framework -> Connector: sync(ObjectClass, syncToken, handler)
activate Connector

alt новый токен (null)
    Connector -> Connector: handleNewToken()
    Connector -> Handler: handleResult(SyncToken(0))
else существующий токен
    Connector -> Connector: token = syncToken.getValue()
    Connector -> Connector: finalToken = newSyncToken()
    
    Connector -> Connector: buildSyncSql()
    note right: SELECT * FROM {table}\nWHERE {changeLogColumn} > {token}\nORDER BY {changeLogColumn} ASC
    
    Connector -> Connection: prepareStatement(sql, params)
    activate Connection
    Connection -> Stmt: setObject(1, token)
    Connection --> Connector: PreparedStatement
    
    Connector -> Stmt: executeQuery()
    activate Stmt
    Stmt --> Connector: ResultSet
    
    loop для каждой изменённой строки
        Connector -> RS: next()
        RS --> Connector: true
        
        Connector -> Connection: getColumnValues(rs)
        Connection --> Connector: Map<String, SQLParam>
        
        Connector -> Connector: buildConnectorObject(columnValues)
        Connector -> Connector: buildSyncDelta(columnValues, finalToken)
        Connector -> Handler: handle(SyncDelta)
    end
    
    RS --> Connector: false (конец)
    deactivate Stmt
    deactivate Connection
    
    Connector -> Handler: handleResult(finalToken)
end

Connector --> Framework: завершено
deactivate Connector
@enduml