single queries for domains to prevent running into the cursor limit

This commit is contained in:
likeazir 2024-11-13 17:49:30 +01:00
parent 86e369201a
commit 6779b5cc43
1 changed files with 31 additions and 30 deletions

View File

@ -382,40 +382,41 @@ public class AccountSessionManager{
} }
private void readInstanceInfo(SQLiteDatabase db, Set<String> domains){ private void readInstanceInfo(SQLiteDatabase db, Set<String> domains){
//limit emoji string to 0.5MB characters to stay under 1MB cursor limit for(String domain : domains){
try(Cursor cursor=db.rawQuery("SELECT domain, instance_obj, substring(emojis,0,500000) AS emojis, length(emojis) AS emojiLength, last_updated, version FROM instances WHERE `domain` IN (" final int maxEmojiLength=500000;
+ String.join(", ", "?".repeat(domains.size())) + ")", domains.toArray(new String[0]))) { try(Cursor cursor=db.rawQuery("SELECT domain, instance_obj, substring(emojis,0,?) AS emojis, length(emojis) AS emojiLength, last_updated, version FROM instances WHERE `domain` = ?",
ContentValues values=new ContentValues(); new String[]{String.valueOf(maxEmojiLength) , domain})) {
while(cursor.moveToNext()){ ContentValues values=new ContentValues();
DatabaseUtils.cursorRowToContentValues(cursor, values); while(cursor.moveToNext()){
String domain=values.getAsString("domain"); DatabaseUtils.cursorRowToContentValues(cursor, values);
int version=values.getAsInteger("version"); int version=values.getAsInteger("version");
Instance instance=MastodonAPIController.gson.fromJson(values.getAsString("instance_obj"), switch(version){ Instance instance=MastodonAPIController.gson.fromJson(values.getAsString("instance_obj"), switch(version){
case 1 -> InstanceV1.class; case 1 -> InstanceV1.class;
case 2 -> InstanceV2.class; case 2 -> InstanceV2.class;
default -> throw new IllegalStateException("Unexpected value: " + version); default -> throw new IllegalStateException("Unexpected value: "+version);
}); });
StringBuilder emojiSB = new StringBuilder(); StringBuilder emojiSB=new StringBuilder();
emojiSB.append(values.getAsString("emojis")); emojiSB.append(values.getAsString("emojis"));
//get emoji in chunks of 1MB if it didn't fit in the first query //get emoji in chunks of 1MB if it didn't fit in the first query
int emojiStringLength = values.getAsInteger("emojiLength"); int emojiStringLength=values.getAsInteger("emojiLength");
if(emojiStringLength > 500000){ if(emojiStringLength>maxEmojiLength){
int pagesize=1000000; final int pagesize=1000000;
for(int start = 500000; start < emojiStringLength; start += pagesize){ for(int start=maxEmojiLength; start<emojiStringLength; start+=pagesize){
try(Cursor emojiCursor=db.rawQuery("select substr(emojis,?, ?) from instances where `domain` = ?", new String[]{String.valueOf(start), String.valueOf(pagesize), domain})){ try(Cursor emojiCursor=db.rawQuery("SELECT substr(emojis,?, ?) FROM instances WHERE `domain` = ?", new String[]{String.valueOf(start), String.valueOf(pagesize), domain})){
emojiCursor.moveToNext(); emojiCursor.moveToNext();
emojiSB.append(emojiCursor.getString(0)); emojiSB.append(emojiCursor.getString(0));
}
} }
} }
List<Emoji> emojis=MastodonAPIController.gson.fromJson(emojiSB.toString(), new TypeToken<List<Emoji>>(){}.getType());
instances.put(domain, instance);
customEmojis.put(domain, groupCustomEmojis(emojis));
instancesLastUpdated.put(domain, values.getAsLong("last_updated"));
} }
List<Emoji> emojis=MastodonAPIController.gson.fromJson(emojiSB.toString(), new TypeToken<List<Emoji>>(){}.getType()); }catch(Exception ex){
instances.put(domain, instance); Log.d(TAG, "readInstanceInfo failed", ex);
customEmojis.put(domain, groupCustomEmojis(emojis)); return;
instancesLastUpdated.put(domain, values.getAsLong("last_updated"));
} }
} catch(Exception ex) {
Log.d(TAG, "readInstanceInfo failed", ex);
return;
} }
if(!loadedInstances){ if(!loadedInstances){
loadedInstances=true; loadedInstances=true;