mirror of
https://github.com/tiennm99/store-scraper-bot-java.git
synced 2026-05-14 11:53:03 +00:00
Refactor repository structure for Couchbase collections
Introduced AbstractCollectionRepository and AbstractSingletonRepository to clarify repository types and encapsulate logic for single-key and collection-based repositories. Updated AdminRepository, AppleAppRepository, GoogleAppRepository, and GroupRepository to extend the appropriate abstract classes. Removed COMMON_COLLECTION_NAME from Constant.java and enforced collection name restrictions in AbstractRepository.
This commit is contained in:
@@ -7,7 +7,6 @@ import java.time.temporal.ChronoUnit;
|
||||
import java.util.Set;
|
||||
|
||||
public class Constant {
|
||||
public static final String COMMON_COLLECTION_NAME = "common";
|
||||
public static final long APP_CACHE_SECONDS = 600;
|
||||
public static final long NUM_DAYS_WARNING_NOT_UPDATED = 30;
|
||||
public static final LocalTime SCHEDULE_CHECK_APP_TIME = LocalTime.of(7, 0);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.miti99.storescraperbot.repository;
|
||||
|
||||
import com.miti99.storescraperbot.model.AbstractModel;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
/**
|
||||
* Các repository tương ứng với 1 Couchbase collection, public các method protected ở class
|
||||
* AbstractRepository để các nơi khác gọi
|
||||
*/
|
||||
@Log4j2
|
||||
public abstract class AbstractCollectionRepository<K, V extends AbstractModel<K>>
|
||||
extends AbstractRepository<K, V> {
|
||||
|
||||
@Override
|
||||
public void init(K key) {
|
||||
super.init(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(K key, V data) {
|
||||
super.save(key, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exist(K key) {
|
||||
return super.exist(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V load(K key) {
|
||||
return super.load(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(K key) {
|
||||
super.delete(key);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.miti99.storescraperbot.repository;
|
||||
|
||||
import static com.miti99.storescraperbot.repository.AbstractSingletonRepository.COMMON_COLLECTION_NAME;
|
||||
|
||||
import com.couchbase.client.java.Collection;
|
||||
import com.couchbase.client.java.kv.UpsertOptions;
|
||||
import com.google.common.base.CaseFormat;
|
||||
@@ -10,9 +12,13 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.time.Duration;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
/**
|
||||
* @param <K> class Key
|
||||
* @param <V> class Value
|
||||
*/
|
||||
@Log4j2
|
||||
public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
public static final String SEPARATOR = "_";
|
||||
protected static final String SEPARATOR = "_";
|
||||
// protected final Class<K> classK = getKeyClass();
|
||||
protected final Class<V> classV = getDataClass();
|
||||
protected final String scopeName = Environment.ENV.name().toLowerCase();
|
||||
@@ -25,6 +31,10 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
|
||||
protected AbstractRepository() {
|
||||
collectionName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, classV.getSimpleName());
|
||||
if (COMMON_COLLECTION_NAME.equals(collectionName)) {
|
||||
throw new RuntimeException(
|
||||
"Collection named '%s' is reserved".formatted(COMMON_COLLECTION_NAME));
|
||||
}
|
||||
CouchbaseUtil.createCollection(scopeName, collectionName);
|
||||
}
|
||||
|
||||
@@ -35,8 +45,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
|
||||
/**
|
||||
* Lấy ra class của V. Khi tạo 1 abstract class extends AbstractRepository mà không phải final thì
|
||||
* sẽ cần override hàm này phù hợp<br>
|
||||
* Chi tiết có thể tìm hiểu thêm về getGenericSuperclass và getParameterizedClass<br>
|
||||
* sẽ cần override hàm này phù hợp
|
||||
*
|
||||
* @return Class<V>
|
||||
*/
|
||||
@@ -56,7 +65,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void init(K key) {
|
||||
protected void init(K key) {
|
||||
try {
|
||||
if (exist(key)) {
|
||||
return;
|
||||
@@ -73,7 +82,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
return String.valueOf(key);
|
||||
}
|
||||
|
||||
public void save(K key, V data) {
|
||||
protected void save(K key, V data) {
|
||||
var databaseKey = getDatabaseKey(key);
|
||||
try {
|
||||
if (getExpireSeconds() == 0) {
|
||||
@@ -88,7 +97,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exist(K key) {
|
||||
protected boolean exist(K key) {
|
||||
var databaseKey = getDatabaseKey(key);
|
||||
try {
|
||||
return collection().exists(databaseKey).exists();
|
||||
@@ -98,7 +107,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
}
|
||||
}
|
||||
|
||||
public V load(K key) {
|
||||
protected V load(K key) {
|
||||
var databaseKey = getDatabaseKey(key);
|
||||
try {
|
||||
var getResult = collection().get(databaseKey);
|
||||
@@ -112,7 +121,7 @@ public abstract class AbstractRepository<K, V extends AbstractModel<K>> {
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(K key) {
|
||||
protected void delete(K key) {
|
||||
var databaseKey = getDatabaseKey(key);
|
||||
try {
|
||||
collection().remove(databaseKey);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.miti99.storescraperbot.repository;
|
||||
|
||||
import com.miti99.storescraperbot.model.AbstractModel;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
/**
|
||||
* Repository chỉ chứa 1 key duy nhất, public các method liên quan nhưng không cho truyền params
|
||||
* vào. Các repository loại này được lưu trong 1 collection duy nhất là "common" (do Couchbase có
|
||||
* giới hạn số lượng collection mỗi cluster nên gom nhóm các repository loại này lại)
|
||||
*/
|
||||
@Log4j2
|
||||
public abstract class AbstractSingletonRepository<K, V extends AbstractModel<K>>
|
||||
extends AbstractRepository<K, V> {
|
||||
|
||||
public static final String COMMON_COLLECTION_NAME = "common";
|
||||
protected final K key = getKey();
|
||||
|
||||
protected AbstractSingletonRepository() {
|
||||
super(COMMON_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
protected abstract K getKey();
|
||||
|
||||
public void init() {
|
||||
init(key);
|
||||
}
|
||||
|
||||
public void save(V data) {
|
||||
save(key, data);
|
||||
}
|
||||
|
||||
public boolean exist() {
|
||||
return exist(key);
|
||||
}
|
||||
|
||||
public V load() {
|
||||
return load(key);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
delete(key);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +1,13 @@
|
||||
package com.miti99.storescraperbot.repository;
|
||||
|
||||
import com.miti99.storescraperbot.constant.Constant;
|
||||
import com.miti99.storescraperbot.model.Admin;
|
||||
|
||||
/**
|
||||
* Đây là repository chỉ chứa 1 key duy nhất. Nên lưu trong default collection của Couchbase
|
||||
* ("_default")
|
||||
*
|
||||
* <p>TODO: Refactor các logic của một single key repository sang abstract class để dễ hiểu hơn.
|
||||
* Code hiện tại này chỉ là trick tạm thời nên chưa tốt lắm. Cần thiết kế lại tốt hơn
|
||||
*/
|
||||
public class AdminRepository extends AbstractRepository<String, Admin> {
|
||||
public class AdminRepository extends AbstractSingletonRepository<String, Admin> {
|
||||
public static final AdminRepository INSTANCE = new AdminRepository();
|
||||
public static final String KEY = "admin";
|
||||
|
||||
public AdminRepository() {
|
||||
super(Constant.COMMON_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(String key) {
|
||||
super.init(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String key, Admin data) {
|
||||
super.save(KEY, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exist(String key) {
|
||||
return super.exist(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Admin load(String key) {
|
||||
return super.load(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String key) {
|
||||
super.delete(KEY);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
init(KEY);
|
||||
}
|
||||
|
||||
public Admin load() {
|
||||
return load(KEY);
|
||||
}
|
||||
|
||||
public void save(Admin data) {
|
||||
save(KEY, data);
|
||||
protected String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.miti99.storescraperbot.repository;
|
||||
import com.miti99.storescraperbot.constant.Constant;
|
||||
import com.miti99.storescraperbot.model.AppleApp;
|
||||
|
||||
public class AppleAppRepository extends AbstractRepository<String, AppleApp> {
|
||||
public class AppleAppRepository extends AbstractCollectionRepository<String, AppleApp> {
|
||||
public static final AppleAppRepository INSTANCE = new AppleAppRepository();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.miti99.storescraperbot.repository;
|
||||
import com.miti99.storescraperbot.constant.Constant;
|
||||
import com.miti99.storescraperbot.model.GoogleApp;
|
||||
|
||||
public class GoogleAppRepository extends AbstractRepository<String, GoogleApp> {
|
||||
public class GoogleAppRepository extends AbstractCollectionRepository<String, GoogleApp> {
|
||||
public static final GoogleAppRepository INSTANCE = new GoogleAppRepository();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,6 @@ package com.miti99.storescraperbot.repository;
|
||||
|
||||
import com.miti99.storescraperbot.model.Group;
|
||||
|
||||
public class GroupRepository extends AbstractRepository<Long, Group> {
|
||||
public class GroupRepository extends AbstractCollectionRepository<Long, Group> {
|
||||
public static final GroupRepository INSTANCE = new GroupRepository();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user