* ShutdownHook: No sessions to save check
ShutdownHook now checks if it needs to save any sessions and does not
start the database if no sessions are unsaved.
* SessionCache.getActiveSessions() now immutable
* [#769] Bukkit and Sponge server shutdown save
Implemented following save procedure for Bukkit:
- On plugin disable check if server is shutting down and save sessions
- Shutdown hook triggered on JVM shutdown calls the same session save
- Save clears sessions from cache, so the sessions are not saved twice
Implemented following save procedure for Sponge:
- Listen for GameStoppingServerEvent
- On plugin disable ask listener if shutting down and save sessions
- Shutdown hook triggered on JVM shutdown calls the same session save
- Save clears sessions from cache, so the sessions are not saved twice
Test:
- Tests ShutdownSave on reload
- Tests ShutdownSave on shutdown
- Tests ShutdownSave on JVM shutdown
These can be summarized in 3 categories of changes:
### Moved SQL queries from `Table` classes to `Queries` classes.
`Table` classes were turned into static information classes that only contain statements and table fields for the tables. Classes with static methods were created that return `Query<T>` objects that can be passed to the Database. This simplifies addition of multi-table queries.
### Changes are now executed via Transactions
A new `Transaction` class was made, and executing row updating statements was limited inside these classes. This allows committing changes once per multiple statements (speedup) and rolling back partial failed transactions (reliability).
### Database ExecutorService and access lock
A single thread executor was added to be in charge of executing Transactions. All submitted transactions will be executed by this one thread.
Queries will be held until database is operational (Patches have been applied). This should alleviate issues such as #893
## Other changes
- SaveOperations, CheckOperations, CountOperations, SearchOperations were all removed. FetchOperations was completely deprecated, but since it is still provided by `PlanAPI` it was kept in place.
`FetchOperations` is scheduled for removal upon implementation of the new PluginData API.
- Database interface was not very useful, so it was changed to make it usable instead of SQLDB.
- [Wrong branch] Moved to using JUnit 5.4 TempDir instead of junitpioneer
- `DataCache` was split off to a separate class `NicknameCache` and `SessionCache` no longer saves the session when ended, responsibility is now with the caller
Fixed SonarCloud smells:
Level blocker:
- Removed 'dbType' field from CreateIndexTransaction (is in Transaction)
- Removed unused 'dbSystem' from AnalysisContainer
This class is no longer required since responsibility of storage of
sessions now lies with the caller and it's functionality can be
achieved by not saving the returned optional.
- Removed TableSqlParser, not used
- Removed Select#from that used Column
- Removed Update#values that used Column
- Removed Insert#values that used Column
- Added a Database Access Lock object
- Access log lets OperationCriticalTransactions through
- Transactions skip query access log check
- executeTransaction returns a Future to allow easier synchronization
- ServerInfo waits for the server to be registered. This could lead
to issues if a new server is registering to old database. It should
not be too big of an issue since no patches need to be applied
on first enable of the database.
- Added database states: CLOSED <-> INITIALIZING -> OPEN -> CLOSED
These two changes allow restricting queries to the database until the
database has properly initialized (Schema is in correct format)
- Removed SQLDB as a Patch class variable
Tests use Guava direct thread executor on the database to reduce
concurrency issues during tests. Another option would be to wait for
each transaction.
- Removed SaveOperations#session
- Removed DBSystem dependency from SessionCache, so SessionCache does
not need to be called from async thread. (SessionCache does not save,
responsibility now with the caller)