|
|
|
|
@ -6,9 +6,9 @@ import static de.srsoftware.tools.Optionals.isSet;
@@ -6,9 +6,9 @@ import static de.srsoftware.tools.Optionals.isSet;
|
|
|
|
|
import static de.srsoftware.tools.jdbc.Condition.equal; |
|
|
|
|
import static de.srsoftware.tools.jdbc.Condition.isNull; |
|
|
|
|
import static de.srsoftware.tools.jdbc.Query.*; |
|
|
|
|
import static de.srsoftware.tools.jdbc.Query.Dialect.SQLITE; |
|
|
|
|
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; |
|
|
|
|
import static de.srsoftware.umbrella.bookmarks.Constants.TABLE_URLS; |
|
|
|
|
import static de.srsoftware.umbrella.bookmarks.Constants.TABLE_URL_COMMENTS; |
|
|
|
|
import static de.srsoftware.umbrella.bookmarks.Constants.*; |
|
|
|
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
|
|
|
import static de.srsoftware.umbrella.core.Constants.ERROR_FAILED_CREATE_TABLE; |
|
|
|
|
import static de.srsoftware.umbrella.core.Constants.USER_ID; |
|
|
|
|
@ -24,8 +24,8 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
@@ -24,8 +24,8 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
|
|
|
|
import java.sql.Connection; |
|
|
|
|
import java.sql.SQLException; |
|
|
|
|
import java.time.LocalDateTime; |
|
|
|
|
import java.time.ZoneOffset; |
|
|
|
|
import java.util.*; |
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
public class SqliteDb extends BaseDb implements TagDB{ |
|
|
|
|
private static final System.Logger LOG = System.getLogger("TagDB"); |
|
|
|
|
@ -49,30 +49,55 @@ public class SqliteDb extends BaseDb implements TagDB{
@@ -49,30 +49,55 @@ public class SqliteDb extends BaseDb implements TagDB{
|
|
|
|
|
createLegacyUrlCommentsTable(); |
|
|
|
|
createLegacyTagsTable(); |
|
|
|
|
case 1: |
|
|
|
|
createNewTagTable(); |
|
|
|
|
splitContentToBookmarks(); |
|
|
|
|
createTagTables(); |
|
|
|
|
dropOldTables(); |
|
|
|
|
renameNewTagTable(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return setCurrentVersion(2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void splitContentToBookmarks() { |
|
|
|
|
var pattern = Pattern.compile("/([^/]+)/(\\d+)/view"); |
|
|
|
|
try { |
|
|
|
|
var sql = "CREATE TABLE IF NOT EXISTS tags_new (TAG)"; |
|
|
|
|
db.prepareStatement(sql).execute(); |
|
|
|
|
// IMPORT BOOKMARKS
|
|
|
|
|
var commentedURLS = select(ALL).from(TABLE_URLS).leftJoin(HASH,TABLE_URL_COMMENTS,URL_HASH).leftJoin(COMMENT_HASH,TABLE_COMMENTS,HASH).exec(db); |
|
|
|
|
|
|
|
|
|
while (commentedURLS.next()){ |
|
|
|
|
var userId = commentedURLS.getLong(USER_ID); |
|
|
|
|
var urlHash = commentedURLS.getString(URL_HASH); |
|
|
|
|
if (userId == 0) continue; |
|
|
|
|
var url = commentedURLS.getString(URL); |
|
|
|
|
LOG.log(DEBUG,url); |
|
|
|
|
var timestamp = commentedURLS.getLong(TIMESTAMP); |
|
|
|
|
var comment = commentedURLS.getString(COMMENT); |
|
|
|
|
if (!isSet(comment)) comment = ""; |
|
|
|
|
var dt = is0(timestamp) ? LocalDateTime.now() : LocalDateTime.ofEpochSecond(timestamp,0,UTC); |
|
|
|
|
bookmarks.save(url,comment,List.of(userId),dt.withNano(0)); |
|
|
|
|
var bm = bookmarks.save(url,comment,List.of(userId),dt.withNano(0)); |
|
|
|
|
|
|
|
|
|
String module = null; |
|
|
|
|
long entityId = 0; |
|
|
|
|
var matcher = pattern.matcher(url); |
|
|
|
|
if (matcher.find()){ |
|
|
|
|
module = matcher.group(1); |
|
|
|
|
entityId = Long.parseLong(matcher.group(2)); |
|
|
|
|
LOG.log(DEBUG,"This module is referring to Umbrella`s {0} {1}",module,entityId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var urlTags = select(ALL).from(TABLE_TAGS).where(URL_HASH,equal(urlHash)).where(USER_ID,equal(userId)).exec(db); |
|
|
|
|
var insertQuery = insertInto(TABLE_TAGS_NEW,TAG,MODULE,ENTITY_ID,USER_ID).ignoreDuplicates(SQLITE); |
|
|
|
|
while (urlTags.next()){ |
|
|
|
|
var tag = urlTags.getString(TAG); |
|
|
|
|
insertQuery.values(tag,BOOKMARK,bm.urlId(),userId); |
|
|
|
|
if (module != null && entityId != 0) insertQuery.values(tag,module,entityId,userId); |
|
|
|
|
} |
|
|
|
|
insertQuery.execute(db).close(); |
|
|
|
|
urlTags.close(); |
|
|
|
|
} |
|
|
|
|
commentedURLS.close(); |
|
|
|
|
|
|
|
|
|
// UPDATE TAGS
|
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
} |
|
|
|
|
@ -127,9 +152,9 @@ public class SqliteDb extends BaseDb implements TagDB{
@@ -127,9 +152,9 @@ public class SqliteDb extends BaseDb implements TagDB{
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void createTagTables() { |
|
|
|
|
private void createNewTagTable() { |
|
|
|
|
var createTable = """ |
|
|
|
|
CREATE TABLE IF NOT EXISTS "{0}" ( |
|
|
|
|
CREATE TABLE IF NOT EXISTS {0} ( |
|
|
|
|
{1} VARCHAR(255) NOT NULL, |
|
|
|
|
{2} VARCHAR(20) NOT NULL, |
|
|
|
|
{3} INTEGER NOT NULL, |
|
|
|
|
@ -137,11 +162,35 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -137,11 +162,35 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
PRIMARY KEY ({1}, {2}, {3}, {4}) |
|
|
|
|
)"""; |
|
|
|
|
try { |
|
|
|
|
var stmt = db.prepareStatement(format(createTable,TABLE_TAGS, TAG, MODULE, ID, USER_ID)); |
|
|
|
|
var stmt = db.prepareStatement(format(createTable,TABLE_TAGS_NEW, TAG, MODULE, ENTITY_ID, USER_ID)); |
|
|
|
|
stmt.execute(); |
|
|
|
|
stmt.close(); |
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_TAGS_NEW,e); |
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void dropOldTables(){ |
|
|
|
|
var sql = "DROP TABLE IF EXISTS {0}"; |
|
|
|
|
for (var table : List.of(TABLE_TAGS,TABLE_COMMENTS,TABLE_TOKENS,TABLE_URL_COMMENTS,TABLE_URLS)) try { |
|
|
|
|
var stmt = db.prepareStatement(format(sql,table)); |
|
|
|
|
stmt.execute(); |
|
|
|
|
stmt.close(); |
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_TAGS_NEW,e); |
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void renameNewTagTable() { |
|
|
|
|
var sql = "ALTER TABLE {0} RENAME TO {1}"; |
|
|
|
|
try { |
|
|
|
|
var stmt = db.prepareStatement(format(sql,TABLE_TAGS_NEW, TABLE_TAGS)); |
|
|
|
|
stmt.execute(); |
|
|
|
|
stmt.close(); |
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_TAGS,e); |
|
|
|
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_TAGS_NEW,e); |
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -150,10 +199,10 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -150,10 +199,10 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
public String delete(long userId, String module, long entityId, String tag) { |
|
|
|
|
try { |
|
|
|
|
Query.delete().from(TABLE_TAGS) |
|
|
|
|
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,equal(userId)) |
|
|
|
|
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId)) |
|
|
|
|
.execute(db); |
|
|
|
|
Query.delete().from(TABLE_TAGS) |
|
|
|
|
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,isNull()) |
|
|
|
|
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull()) |
|
|
|
|
.execute(db); |
|
|
|
|
return tag; |
|
|
|
|
} catch (SQLException e){ |
|
|
|
|
@ -165,7 +214,7 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -165,7 +214,7 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
public void deleteEntity(String module, long entityId) { |
|
|
|
|
try { |
|
|
|
|
Query.delete().from(TABLE_TAGS) |
|
|
|
|
.where(MODULE,equal(module)).where(ID,equal(entityId)) |
|
|
|
|
.where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)) |
|
|
|
|
.execute(db); |
|
|
|
|
} catch (SQLException e){ |
|
|
|
|
throw new UmbrellaException("Failed to save tags ({0} {1})",module,entityId); |
|
|
|
|
@ -179,14 +228,14 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -179,14 +228,14 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
var result = new HashMap<String,List<Long>>(); |
|
|
|
|
while (rs.next()){ |
|
|
|
|
var module = rs.getString(MODULE); |
|
|
|
|
var entityId = rs.getLong(ID); |
|
|
|
|
var entityId = rs.getLong(ENTITY_ID); |
|
|
|
|
result.computeIfAbsent(module, k -> new ArrayList<>()).add(entityId); |
|
|
|
|
} |
|
|
|
|
rs.close(); |
|
|
|
|
rs = select(ALL).from(TABLE_TAGS).where(TAG,equal(tag)).where(USER_ID,isNull()).exec(db); |
|
|
|
|
while (rs.next()){ |
|
|
|
|
var module = rs.getString(MODULE); |
|
|
|
|
var entityId = rs.getLong(ID); |
|
|
|
|
var entityId = rs.getLong(ENTITY_ID); |
|
|
|
|
result.computeIfAbsent(module, k -> new ArrayList<>()).add(entityId); |
|
|
|
|
} |
|
|
|
|
rs.close(); |
|
|
|
|
@ -205,9 +254,9 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -205,9 +254,9 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
public Set<String> list(long userId, String module, long entityId) { |
|
|
|
|
try { |
|
|
|
|
var tags = new HashSet<String>(); |
|
|
|
|
var rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,equal(userId)).exec(db); |
|
|
|
|
var rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId)).exec(db); |
|
|
|
|
while (rs.next()) tags.add(rs.getString(1)); |
|
|
|
|
rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,isNull()).exec(db); |
|
|
|
|
rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull()).exec(db); |
|
|
|
|
while (rs.next()) tags.add(rs.getString(1)); |
|
|
|
|
rs.close(); |
|
|
|
|
return tags; |
|
|
|
|
@ -219,7 +268,7 @@ CREATE TABLE IF NOT EXISTS "{0}" (
@@ -219,7 +268,7 @@ CREATE TABLE IF NOT EXISTS "{0}" (
|
|
|
|
|
@Override |
|
|
|
|
public void save(Collection<Long> userIds, String module, long entityId, Collection<String> tags) { |
|
|
|
|
try { |
|
|
|
|
var query = replaceInto(TABLE_TAGS,USER_ID,MODULE,ID,TAG); |
|
|
|
|
var query = replaceInto(TABLE_TAGS,USER_ID,MODULE,ENTITY_ID,TAG); |
|
|
|
|
for (var tag : tags) { |
|
|
|
|
if (userIds == null) { // tags not assigned to a user are available to all users
|
|
|
|
|
query.values(null, module, entityId, tag); |
|
|
|
|
|