fix(mongo): codec

This commit is contained in:
2025-12-16 21:57:57 +07:00
parent 9a2e9347da
commit 7d42d621e9
8 changed files with 36 additions and 25 deletions
@@ -1,22 +1,21 @@
package com.miti99.storescraperbot.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.google.gson.annotations.SerializedName;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Con của AbstractModel phải có getter, setter & field không được final thì mới deserialize được
*/
@Getter
@NoArgsConstructor
@Setter
public abstract class AbstractModel<K> {
@JsonSetter(nulls = Nulls.SKIP)
protected K key;
public abstract class AbstractModel {
@SerializedName("_id")
protected String id;
@JsonProperty("class")
@SerializedName("class")
protected String clazz = getClass().getSimpleName();
public void setId(Object id) {
this.id = String.valueOf(id);
}
}
@@ -7,6 +7,6 @@ import lombok.Setter;
@Getter
@Setter
public class Admin extends AbstractModel<String> {
public class Admin extends AbstractModel {
Set<Long> groups = new HashSet<>();
}
@@ -6,7 +6,7 @@ import lombok.Setter;
@Getter
@Setter
public class AppleApp extends AbstractModel<String> {
public class AppleApp extends AbstractModel {
AppleAppResponse app;
long millis; // TODO: handle expire
}
@@ -6,7 +6,7 @@ import lombok.Setter;
@Getter
@Setter
public class GoogleApp extends AbstractModel<String> {
public class GoogleApp extends AbstractModel {
GoogleAppResponse app;
long millis; // TODO: handle expire
}
@@ -9,7 +9,7 @@ import lombok.Setter;
@Getter
@Setter
public class Group extends AbstractModel<Long> {
public class Group extends AbstractModel {
List<AppleAppInfo> appleApps = new ArrayList<>();
List<GoogleAppInfo> googleApps = new ArrayList<>();
}
@@ -8,7 +8,7 @@ import lombok.extern.log4j.Log4j2;
* AbstractRepository để các nơi khác gọi
*/
@Log4j2
public abstract class AbstractCollectionRepository<K, V extends AbstractModel<K>>
public abstract class AbstractCollectionRepository<K, V extends AbstractModel>
extends AbstractRepository<K, V> {
@Override
@@ -4,27 +4,31 @@ import static com.miti99.storescraperbot.repository.AbstractSingletonRepository.
import com.google.common.base.CaseFormat;
import com.miti99.storescraperbot.model.AbstractModel;
import com.miti99.storescraperbot.util.GsonUtil;
import com.miti99.storescraperbot.util.MongoDBUtil;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.ReplaceOptions;
import java.lang.reflect.ParameterizedType;
import lombok.extern.log4j.Log4j2;
import org.bson.Document;
/**
* @param <K> class Key
* @param <V> class Value
*/
@Log4j2
public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
public abstract class AbstractRepository<K, V extends AbstractModel> {
protected static final String SEPARATOR = "_";
// protected final Class<K> classK = getKeyClass();
protected final Class<V> classV = getDataClass();
protected final String collectionName;
protected final MongoCollection<Document> collection;
protected AbstractRepository(String collectionName) {
this.collectionName = collectionName;
MongoDBUtil.createCollectionIfNotExists(collectionName);
collection = MongoDBUtil.DATABASE.getCollection(collectionName, Document.class);
}
protected AbstractRepository() {
@@ -34,6 +38,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
"Collection named '%s' is reserved".formatted(COMMON_COLLECTION_NAME));
}
MongoDBUtil.createCollectionIfNotExists(collectionName);
collection = MongoDBUtil.DATABASE.getCollection(collectionName, Document.class);
}
// protected Class<K> getKeyClass() {
@@ -52,8 +57,12 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
protected MongoCollection<V> collection() {
return MongoDBUtil.DATABASE.getCollection(collectionName, classV);
protected String encode(V data) {
return GsonUtil.toJson(data);
}
protected V decode(String json) {
return GsonUtil.fromJson(json, classV);
}
protected void init(K key) {
@@ -62,7 +71,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
return;
}
V data = classV.getDeclaredConstructor().newInstance();
data.setKey(key);
data.setId(key);
save(key, data);
} catch (Exception e) {
log.error("Error while initializing data", e);
@@ -76,8 +85,9 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
protected void save(K key, V data) {
var databaseKey = getDatabaseKey(key);
try {
collection()
.replaceOne(Filters.eq("_id", databaseKey), data, new ReplaceOptions().upsert(true));
var json = encode(data);
var doc = Document.parse(json);
collection.replaceOne(Filters.eq("_id", databaseKey), doc, new ReplaceOptions().upsert(true));
} catch (Exception e) {
log.error("save error - key {}, databaseKey {}", key, databaseKey, e);
}
@@ -86,7 +96,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
protected boolean exist(K key) {
var databaseKey = getDatabaseKey(key);
try {
return collection().countDocuments(Filters.eq("_id", databaseKey)) > 0;
return collection.countDocuments(Filters.eq("_id", databaseKey)) > 0;
} catch (Exception e) {
log.error("exist error - key {}, databaseKey {}", key, databaseKey, e);
return false;
@@ -96,7 +106,9 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
protected V load(K key) {
var databaseKey = getDatabaseKey(key);
try {
return collection().find(Filters.eq("_id", databaseKey)).first();
var doc = collection.find(Filters.eq("_id", databaseKey)).first();
if (doc == null) return null;
return decode(doc.toJson());
} catch (Exception e) {
log.error("load error - key {}, databaseKey {}", key, databaseKey, e);
return null;
@@ -106,7 +118,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
protected void delete(K key) {
var databaseKey = getDatabaseKey(key);
try {
collection().deleteOne(Filters.eq("_id", databaseKey));
collection.deleteOne(Filters.eq("_id", databaseKey));
} catch (Exception e) {
log.error("delete error", e);
}
@@ -8,7 +8,7 @@ import lombok.extern.log4j.Log4j2;
* vào. Các repository loại này được lưu trong 1 collection duy nhất là "common"
*/
@Log4j2
public abstract class AbstractSingletonRepository<K, V extends AbstractModel<K>>
public abstract class AbstractSingletonRepository<K, V extends AbstractModel>
extends AbstractRepository<K, V> {
public static final String COMMON_COLLECTION_NAME = "common";