Class MysqlDataStore
- All Implemented Interfaces:
DataStore
DataStore.
There is exactly one global HikariDataSource for the whole server (constructed once
from config.yml's mysql.* settings), so re-scoping does not move any MySQL data
-- but the operator cache below is keyed by (requesting identity, entity class), not by entity
class alone, so two plugins sharing an entity class no longer share one DataOperator
instance and cannot read each other's rows through it (SILENT-04). Neither map is
static: DataStoreManager registers exactly one MysqlDataStore instance.
- Version:
- 1.0.0
- Author:
- wisdomme
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final classComposite operator-cache key: the requesting identity (plugin name on the plugin path, canonical data-folder path on the externalFilepath) plus the entity class. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final Map<MysqlDataStore.OperatorKey, DataOperator<?>> Operator cache, keyed by (requesting identity, entity class).private com.zaxxer.hikari.HikariDataSourceprivate final Map<String, JdbcTransactionManager> JdbcTransactionManagercache, keyed by requesting identity -- one manager per plugin container even though every plugin shares the one globaldataSource(D-02):contextHolderis a per-instanceThreadLocal(FOUND-04), so two plugins each doing a@Transactionalwrite on MySQL must never cross transaction state, exactly asPluginManager.wireTransactional's own javadoc already documents for the JDBC path. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) static com.zaxxer.hikari.HikariConfigbuildConfig(MysqlConfig mysqlConfig) Builds the pool configuration without opening a database connection.private static StringcanonicalPath(File dataFolder) voidSave all possible caches and destroy all data operation classes.getDataSource(DataScope scope) Get the JDBCDataSourcebacking this store for the given scope, needing no entity class up front (a connection pool needs only a JDBC URL).<T extends BaseDataEntity<String>>
DataOperator<T> getOperator(UltiToolsPlugin plugin, Class<T> dataEntity) Get data operation entity class.<T extends BaseDataEntity<String>>
DataOperator<T> getOperator(File dataFolder, Class<T> dataEntity) Get data operator for an external plugin, scoped to the plugin's own data folder.private <T extends BaseDataEntity<String>>
DataOperator<T> getOperatorForIdentity(String identity, Class<T> dataEntity) Shared operator-construction body for all three entry points above, once ownership has already been established by whichever one of them was called.<T extends BaseDataEntity<String>>
DataOperator<T> getOperatorUnchecked(DataScope scope, Class<T> dataEntity) Internal, unchecked construction path (CR-01/CR-03, 02-13):DataStore.getOperator(DataScope, Class)'s default body calls this only after its ownscope.owns(...)check has already passed.Get the type of data storage.private static StringidentityFor(DataScope scope) Resolvesscope's operator-cache identity, matching whichever legacygetOperatoroverload the same scope would actually route through: the internal (plugin name) shape whenscopeis an internal plugin's own scope (itsdataFolderis exactly the core framework's own data folder,DataScope.forPlugin's construction -- the same disambiguationJsonStore.identityOf(DataScope)andSQLiteDataStore.dbPathFor(DataScope)use, 02-05), the external (canonical folder path) shape otherwise.transactionManagerFor(DataScope scope) Resolves the same per-plugin-containerJdbcTransactionManagerinstancegetOperator(com.ultikits.ultitools.abstracts.UltiToolsPlugin, java.lang.Class<T>)wires onto the operators it hands out forscope's own identity -- the seamPluginManager.wireTransactionalcalls to bind the AOP@Transactionalinterceptor to it, so a module's data operators and its@Transactionalbeans share one transaction, not two (T-02-TAM-11), despite every plugin sharing the one globaldataSource.private JdbcTransactionManagertransactionManagerForIdentity(String identity) Returns the manager foridentity, building it on first touch.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.ultikits.ultitools.interfaces.DataStore
checkOwnership, checkOwnership, getOperator
-
Field Details
-
dataOperatorMap
Operator cache, keyed by (requesting identity, entity class). Not static -- see class javadoc. Deliberately not Lombok-@Getter'd -- it must stay encapsulated, unlikedataSourcebelow which the framework already exposes. -
dataSource
private com.zaxxer.hikari.HikariDataSource dataSource -
transactionManagerMap
JdbcTransactionManagercache, keyed by requesting identity -- one manager per plugin container even though every plugin shares the one globaldataSource(D-02):contextHolderis a per-instanceThreadLocal(FOUND-04), so two plugins each doing a@Transactionalwrite on MySQL must never cross transaction state, exactly asPluginManager.wireTransactional's own javadoc already documents for the JDBC path. Not static -- same reload-safety reasoning asdataOperatorMap.The single seam through which both
transactionManagerFor(DataScope)(called byPluginManager.wireTransactionalfor the AOP interceptor) andgetOperator(com.ultikits.ultitools.abstracts.UltiToolsPlugin, java.lang.Class<T>)(below) resolve a manager for the same identity --computeIfAbsentguarantees the second caller gets back the exact instance the first one built (T-02-TAM-11).
-
-
Constructor Details
-
MysqlDataStore
public MysqlDataStore()
-
-
Method Details
-
buildConfig
Builds the pool configuration without opening a database connection. -
getStoreType
Description copied from interface:DataStoreGet the type of data storage.- Specified by:
getStoreTypein interfaceDataStore- Returns:
- Data storage type
-
getOperator
public <T extends BaseDataEntity<String>> DataOperator<T> getOperator(UltiToolsPlugin plugin, Class<T> dataEntity) Description copied from interface:DataStoreGet data operation entity class.- Specified by:
getOperatorin interfaceDataStore- Type Parameters:
T- Must inheritBaseDataEntity- Parameters:
plugin- PlugindataEntity- Data entity class- Returns:
- Data operation entity
-
getOperator
public <T extends BaseDataEntity<String>> DataOperator<T> getOperator(File dataFolder, Class<T> dataEntity) Description copied from interface:DataStoreGet data operator for an external plugin, scoped to the plugin's own data folder. Refuses outright (D-18) whendataFolderresolves to a registered external plugin's scope that does not owndataEntity, or whendataFoldermatches no registered scope at all -- an unresolvable folder fails closed rather than proceeding unchecked (D-15). ADataStorethat overrides this method directly (as every backend shipped by this framework does) does not inherit this check; see the@deprecatednote.- Specified by:
getOperatorin interfaceDataStore- Type Parameters:
T- entity type- Parameters:
dataFolder- the external plugin's data folder (e.g., plugins/MyPlugin/)dataEntity- data entity class- Returns:
- data operator
-
getOperatorUnchecked
public <T extends BaseDataEntity<String>> DataOperator<T> getOperatorUnchecked(DataScope scope, Class<T> dataEntity) Internal, unchecked construction path (CR-01/CR-03, 02-13):DataStore.getOperator(DataScope, Class)'s default body calls this only after its ownscope.owns(...)check has already passed. Resolvesscopeto the exact same identityidentityFor(DataScope)already derives fortransactionManagerFor(DataScope)-- internal scopes resolve to the plugin's own name, external scopes to the canonical data-folder path -- so an internal scope's operator cache entry is keyed identically whether reached through here or throughgetOperator(UltiToolsPlugin, Class).- Specified by:
getOperatorUncheckedin interfaceDataStore- Type Parameters:
T- Must inheritBaseDataEntity- Parameters:
scope- the requesting scope, already verified to owndataEntitydataEntity- data entity class- Returns:
- data operator for that entity
-
getOperatorForIdentity
private <T extends BaseDataEntity<String>> DataOperator<T> getOperatorForIdentity(String identity, Class<T> dataEntity) Shared operator-construction body for all three entry points above, once ownership has already been established by whichever one of them was called. Single-sourced so the operator cache (keyed by (identity, entity)) and thetransactionManagerForIdentitywiring are each written in exactly one place. -
getDataSource
Description copied from interface:DataStoreGet the JDBCDataSourcebacking this store for the given scope, needing no entity class up front (a connection pool needs only a JDBC URL).- Specified by:
getDataSourcein interfaceDataStore- Parameters:
scope- the requesting scope- Returns:
- the JDBC data source for that scope
-
transactionManagerFor
Resolves the same per-plugin-containerJdbcTransactionManagerinstancegetOperator(com.ultikits.ultitools.abstracts.UltiToolsPlugin, java.lang.Class<T>)wires onto the operators it hands out forscope's own identity -- the seamPluginManager.wireTransactionalcalls to bind the AOP@Transactionalinterceptor to it, so a module's data operators and its@Transactionalbeans share one transaction, not two (T-02-TAM-11), despite every plugin sharing the one globaldataSource.- Parameters:
scope- the identity token to resolve the manager for- Returns:
- the shared manager for that scope's identity
-
identityFor
Resolvesscope's operator-cache identity, matching whichever legacygetOperatoroverload the same scope would actually route through: the internal (plugin name) shape whenscopeis an internal plugin's own scope (itsdataFolderis exactly the core framework's own data folder,DataScope.forPlugin's construction -- the same disambiguationJsonStore.identityOf(DataScope)andSQLiteDataStore.dbPathFor(DataScope)use, 02-05), the external (canonical folder path) shape otherwise. Shared bytransactionManagerFor(DataScope)andgetOperatorUnchecked(DataScope, Class)(02-13) so the two never disagree on identity. -
transactionManagerForIdentity
Returns the manager foridentity, building it on first touch. -
canonicalPath
-
destroyAllOperators
public void destroyAllOperators()Description copied from interface:DataStoreSave all possible caches and destroy all data operation classes.- Specified by:
destroyAllOperatorsin interfaceDataStore
-