Class SimpleJsonDataOperator<T extends BaseDataEntity<String>>
- Type Parameters:
T- Data type inherited from BaseDataEntity
- All Implemented Interfaces:
Cached,DataOperator<T>
- Version:
- 1.0.0
- Author:
- wisdomme
-
Nested Class Summary
Nested classes/interfaces inherited from interface com.ultikits.ultitools.interfaces.DataOperator
DataOperator.LikeType -
Field Summary
FieldsModifier and TypeFieldDescriptionSQL column name (lowercase) -> Java field name.private static final com.google.gson.GsonDefault Gson has no bundled adapter forjava.time.LocalDateTime: its reflective fallback tries to reachLocalDateTime's private fields, which JDK 9+'s module system refuses without--add-opens java.base/java.time, throwingJsonIOExceptionthe first time this operator serializes an entity carrying a non-nullLocalDateTime-typed@Column(02-08 --AuditableDataEntity#createdAt/updatedAtwere alwaysnullbefore this plan, so the whole-entityGSON.toJson(...)calls below never reached this type until the lifecycle hooks started populating it).private final Stringprivate JsonTransactionManagerThe per-pluginJsonTransactionManagergoverning this operator, ornullif this operator was never bound to one (e.g. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate voidCalled as the first statement of every cache-mutating method (insert(T),del(com.ultikits.ultitools.entities.WhereCondition...),delById(java.lang.Object), the twoupdateoverloads).(package private) voidbindTransactionManager(JsonTransactionManager transactionManager) Binds theJsonTransactionManagerthis operator participates in (02-05, D-03).buildColumnToFieldName(Class<?> type) Builds the "SQL column name -> Java field name" mapping from the entity class's@Columnannotations.private booleanconditionCal(String data, String value, WhereCondition condition) voiddel(WhereCondition... whereConditions) Deletes by predicate, without loading matched entries into entities first.voidDeletes by id, fetching the entity first soonDelete()can fire on it -- unlikedel(WhereCondition...), which deletes by predicate without materializing entries and therefore does not fire the hook.booleanexist(WhereCondition... whereConditions) Check if the data record exists.booleanCheck if the data record exists.voidflush()Persist cache object.voidgc()Compare local with cache and delete local persistent files.getAll()Get all data record.getAll(WhereCondition... whereConditions) FiresonLoad()once per entity actually returned to the caller.getAllRaw(WhereCondition... whereConditions) Get data record by ID.getLike(String column, String value, DataOperator.LikeType likeType) Fuzzy QueryvoidInsert data record.voidInsert multiple entities atomically.page(int page, int size, WhereCondition... whereConditions) Get data record by page.private StringresolveColumn(String column) Resolves the caller-supplied column name into the key used in the Gson-serialized map.(package private) voidrestoreCache(Map<Object, T> snapshot) Restores this operator's cache from a snapshot previously captured bysnapshotCache().Deep-copies this operator's current cache: serialize/deserialize to break references, sinceupdate(T)mutates cached entities in-place viaBeanCopyUtil.copyProperties(java.lang.Object, java.lang.Object).private StringstripJsonQuotes(String jsonValue) Remove JSON quotes from a serialized string value.voidtransaction(Runnable action) Execute operations within a transaction (void variant).<R> Rtransaction(Callable<R> action) Execute operations within a transaction.uncheckedCast(Object snapshot) voidUpdate one field of one record.voidUpdate data record by object.voidUpdate multiple entities atomically.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.DataOperator
query
-
Field Details
-
GSON
private static final com.google.gson.Gson GSONDefault Gson has no bundled adapter forjava.time.LocalDateTime: its reflective fallback tries to reachLocalDateTime's private fields, which JDK 9+'s module system refuses without--add-opens java.base/java.time, throwingJsonIOExceptionthe first time this operator serializes an entity carrying a non-nullLocalDateTime-typed@Column(02-08 --AuditableDataEntity#createdAt/updatedAtwere alwaysnullbefore this plan, so the whole-entityGSON.toJson(...)calls below never reached this type until the lifecycle hooks started populating it). MirrorsAbstractRelationalDataOperator's identical adapter (02-08), serializing to/fromLocalDateTime.toString()'s ISO-8601 form. -
storeLocation
-
type
-
cache
-
columnToFieldName
SQL column name (lowercase) -> Java field name.Callers always query using the SQL column name declared on
@Column(52 call sites across 17 Modules), but the key Gson serializes into the map is the Java field name -- the two don't line up on snake_case vs. camelCase, and the query would silently return zero hits. This map translates the former into the latter, matching the read pathAbstractRelationalDataOperator#getListHandler()already uses. See issue #176. -
transactionManager
The per-pluginJsonTransactionManagergoverning this operator, ornullif this operator was never bound to one (e.g. constructed directly, as every pre-existing caller of the two-arg constructor still does -- seetransaction(Callable), which is a separate, independent snapshot mechanism this field does not affect).Set via
bindTransactionManager(JsonTransactionManager)byJsonStore(same package) right after this operator is constructed or retrieved from its cache (02-05, D-03).volatilebecause a write can happen on a different Bukkit worker thread than the one that bound the manager.
-
-
Constructor Details
-
SimpleJsonDataOperator
-
-
Method Details
-
bindTransactionManager
Binds theJsonTransactionManagerthis operator participates in (02-05, D-03).Package-private: called only by
JsonStore, right after it constructs or retrieves this operator from its cache, with the manager it resolves for the same identity. Not part of this class's public API.- Parameters:
transactionManager- the manager governing the plugin (or external caller) this operator belongs to
-
beforeMutate
private void beforeMutate()Called as the first statement of every cache-mutating method (insert(T),del(com.ultikits.ultitools.entities.WhereCondition...),delById(java.lang.Object), the twoupdateoverloads). A no-op unless aboundJsonTransactionManagerhas an active transaction on this thread and has not already captured this operator this transaction (D-03: lazy snapshot on first touch, so an operator never written to during the transaction is neither snapshotted nor restored).The actual deep-copy capture (
snapshotCache()) and restore (restoreCache(Map)) stay entirely inside this class;JsonTransactionManageronly ever holds theSupplier/Consumerlambdas below, never this operator's cache directly. -
uncheckedCast
-
snapshotCache
Deep-copies this operator's current cache: serialize/deserialize to break references, sinceupdate(T)mutates cached entities in-place viaBeanCopyUtil.copyProperties(java.lang.Object, java.lang.Object). Package-private hook shared bytransaction(Callable)(the pre-existing per-operator mechanism, unchanged) andbeforeMutate()(the new per-pluginJsonTransactionManagerhook, 02-05) -- one copy of the deep-copy logic, two callers. -
restoreCache
Restores this operator's cache from a snapshot previously captured bysnapshotCache(). -
buildColumnToFieldName
Builds the "SQL column name -> Java field name" mapping from the entity class's@Columnannotations. Collected along the inheritance chain, so the@Column("id")inherited fromBaseDataEntityis included too.- Parameters:
type- the entity type- Returns:
- an unmodifiable map keyed by the lowercased SQL column name
-
resolveColumn
Resolves the caller-supplied column name into the key used in the Gson-serialized map.- Parameters:
column- the caller-supplied column name, which may be a SQL column name, a Java field name, or a nested path- Returns:
- a key or path that can be passed directly to
JsonPathUtil
-
exist
Description copied from interface:DataOperatorCheck if the data record exists.- Specified by:
existin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
object- Data record entity- Returns:
- Whether the record exists
-
exist
Description copied from interface:DataOperatorCheck if the data record exists.- Specified by:
existin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
whereConditions- Conditions- Returns:
- Whether the record exists
-
getById
Description copied from interface:DataOperatorGet data record by ID.- Specified by:
getByIdin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
id- Record ID- Returns:
- Data record
-
getAll
Description copied from interface:DataOperatorGet all data record.- Specified by:
getAllin interfaceDataOperator<T extends BaseDataEntity<String>>- Returns:
- Data record list
-
getAll
FiresonLoad()once per entity actually returned to the caller. Delegates the matching logic togetAllRaw(com.ultikits.ultitools.entities.WhereCondition...), whichexist(WhereCondition...)andpage(int, int, com.ultikits.ultitools.entities.WhereCondition...)also call directly --existbecause a boolean check should not fire a load hook, andpagebecause firing on every matched row (rather than only the page's slice) would fireonLoad()for entities the caller never actually receives.- Specified by:
getAllin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
whereConditions- Conditions- Returns:
- Data record list
-
getAllRaw
-
getLike
Description copied from interface:DataOperatorFuzzy Query- Specified by:
getLikein interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
column- Column namevalue- Query valuelikeType- Like type- Returns:
- Data record list
-
page
Description copied from interface:DataOperatorGet data record by page.- Specified by:
pagein interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
page- Page numbersize- Page sizewhereConditions- Conditions- Returns:
- Data record list
-
insert
Description copied from interface:DataOperatorInsert data record.- Specified by:
insertin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
obj- Data record
-
del
Deletes by predicate, without loading matched entries into entities first. Consequently this overload does not fireonDelete()-- there is no entity to fire it on without fabricating one, and this class does not fabricate entities to satisfy a hook.delById(Object)fetches the entity first and does fireonDelete()on it (02-08-PLAN.md's delete-hook-path split, mirrored fromAbstractRelationalDataOperator).A
nullor zero-lengthwhereConditionsis refused with aDataAccessException, matchingAbstractRelationalDataOperator.del()'s guard and the contractDataOperator.del(com.ultikits.ultitools.entities.WhereCondition...)'s interface javadoc promises (CR-02, 02-13). The refusal runs beforebeforeMutate(), so a refused call does not capture a transaction snapshot as a side effect.- Specified by:
delin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
whereConditions- Conditions
-
delById
Deletes by id, fetching the entity first soonDelete()can fire on it -- unlikedel(WhereCondition...), which deletes by predicate without materializing entries and therefore does not fire the hook. If no entry matchesid, nothing fires. Reads the cache directly (notgetById(java.lang.Object)) so this does not also fireonLoad()-- deleting is not loading.- Specified by:
delByIdin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
id- Record ID
-
update
Description copied from interface:DataOperatorUpdate one field of one record.- Specified by:
updatein interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
column- Column namevalue- New valueid- Record ID
-
update
Description copied from interface:DataOperatorUpdate data record by object. It will not update the fields that the incoming entity does not have.- Specified by:
updatein interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
obj- Data record
-
flush
public void flush()Description copied from interface:CachedPersist cache object. -
gc
public void gc()Description copied from interface:CachedCompare local with cache and delete local persistent files. -
transaction
Description copied from interface:DataOperatorExecute operations within a transaction. All operations commit together or roll back on exception. For SQL backends, uses database transactions. For JSON, uses snapshot-based rollback.- Specified by:
transactionin interfaceDataOperator<T extends BaseDataEntity<String>>- Type Parameters:
R- the return type- Parameters:
action- the operations to execute- Returns:
- the result of the action
- Throws:
Exception- if the action fails
-
transaction
Description copied from interface:DataOperatorExecute operations within a transaction (void variant).- Specified by:
transactionin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
action- the operations to execute
-
insertAll
Description copied from interface:DataOperatorInsert multiple entities atomically. Uses JDBC batch for SQL backends.- Specified by:
insertAllin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
entities- the entities to insert
-
updateAll
Description copied from interface:DataOperatorUpdate multiple entities atomically. Uses JDBC batch for SQL backends.- Specified by:
updateAllin interfaceDataOperator<T extends BaseDataEntity<String>>- Parameters:
entities- the entities to update- Throws:
IllegalAccessException- if field access fails
-
conditionCal
-
stripJsonQuotes
Remove JSON quotes from a serialized string value. e.g., "\"hello\"" becomes "hello"
-