Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class DdonDatabaseBuilder
{
private const string DefaultSchemaFile = "Script/schema_sqlite.sql";

public const uint Version = 43;
public const uint Version = 44;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as #822, we have to be careful with the merged

private static readonly ILogger Logger = LogProvider.Logger<Logger>(typeof(DdonDatabaseBuilder));

public static IDatabase Build(DatabaseSetting settings)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE "ddon_clan_requests"
(
"requester_character_id" INTEGER PRIMARY KEY NOT NULL,
"clan_id" INTEGER NOT NULL,
"created" DATETIME NOT NULL,
"approved" SMALLINT NOT NULL,
CONSTRAINT "fk_ddon_clan_requests_clan_id" FOREIGN KEY ("clan_id") REFERENCES "ddon_clan_param" ("clan_id") ON DELETE CASCADE,
CONSTRAINT "fk_ddon_clan_requests_requester_character_id" FOREIGN KEY ("requester_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
);

INSERT INTO "ddon_schedule_next" ("type", "timestamp")
VALUES (25, 0);
11 changes: 11 additions & 0 deletions Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1022,3 +1022,14 @@ CREATE TABLE IF NOT EXISTS "ddon_job_emblem" (
CONSTRAINT pk_ddon_job_emblem PRIMARY KEY ("character_id", "job_id"),
CONSTRAINT fk_ddon_job_emblem_character_id FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS "ddon_clan_requests" (
"requester_character_id" INTEGER PRIMARY KEY NOT NULL,
"clan_id" INTEGER NOT NULL,
"created" DATETIME NOT NULL,
"approved" SMALLINT NOT NULL,
CONSTRAINT "fk_ddon_clan_requests_clan_id" FOREIGN KEY ("clan_id") REFERENCES "ddon_clan_param" ("clan_id") ON DELETE CASCADE,
CONSTRAINT "fk_ddon_clan_requests_requester_character_id" FOREIGN KEY ("requester_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE
);
INSERT INTO "ddon_schedule_next" ("type", "timestamp")
VALUES (25, 0);
7 changes: 7 additions & 0 deletions Arrowgene.Ddon.Database/IDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,13 @@ bool InsertBBMContentTreasure(
bool InsertOrUpdateClanBaseCustomization(uint clanId, byte type, uint furnitureId, DbConnection? connectionIn = null);
bool DeleteClanBaseCustomization(uint clanId, byte type, DbConnection? connectionIn = null);
List<CDataClanSearchResult> SearchClans(CDataClanSearchParam param, DbConnection? connectionIn = null);
bool InsertClanRequest(uint clanId, uint characterId, DbConnection? connectionIn = null);
List<CDataClanJoinRequest> GetClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering there can only be one application, shouldn't these return a single entity instead of a list?

List<CDataClanJoinRequest> GetApprovedClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null);
List<CDataClanJoinRequest> GetClanRequestsByClan(uint clanId, DbConnection? connectionIn = null);
bool SetClanRequestApproved(uint characterId, DbConnection? connectionIn = null);
bool DeleteClanRequestByCharacter(uint characterId, DbConnection? connectionIn = null);
bool DeleteOldClanRequests(uint minDays = 30, DbConnection? connectionIn = null);

// Epitaph Road
bool InsertEpitaphRoadUnlock(uint characterId, uint epitaphId, DbConnection? connectionIn = null);
Expand Down
1 change: 1 addition & 0 deletions Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbClan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public partial class DdonSqlDb : SqlDb
+ "AND (@dont_filter_by_active_days OR active_days & @active_days > 0) "
+ "AND (@dont_filter_by_active_time OR active_time & @active_time > 0) "
+ "AND (@dont_filter_by_characteristic OR characteristic & @characteristic > 0) "
+ "AND is_publish = 1 "
+ "LIMIT 256;"; // limit imposed by client

private readonly string SqlSelectClanShopPurchases = $"SELECT {BuildQueryField(ClanShopFields)} FROM \"ddon_clan_shop_purchases\" WHERE \"clan_id\" = @clan_id;";
Expand Down
196 changes: 196 additions & 0 deletions Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbClanRequests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Ddon.Shared.Entity.Structure;
using System.Collections.Generic;
using System.Data.Common;
using System;

namespace Arrowgene.Ddon.Database.Sql.Core
{
public partial class DdonSqlDb : SqlDb
{
/* ddon_clan_requests */
protected static readonly string[] ClanRequestFields = new[]
{
"clan_id", "requester_character_id", "created", "approved"
};

private readonly string SqlInsertClanRequest = $"""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today I learned that C# will let you combine interpolated strings and raw strings.

INSERT INTO ddon_clan_requests ({BuildQueryField(ClanRequestFields)})
VALUES ({BuildQueryInsert(ClanRequestFields)});
""";

private readonly string SqlSelectClanRequestsByCharacter = $"""
SELECT req."clan_id", req."requester_character_id", req."created", req."approved", chara."first_name", chara."last_name", param."name"
FROM ddon_clan_requests AS req
INNER JOIN ddon_character AS chara ON req.requester_character_id = chara.character_id
INNER JOIN ddon_clan_param AS param ON param.clan_id = req.clan_id
WHERE req.requester_character_id = @requester_character_id
AND req.approved = 0;
""";

private readonly string SqlSelectApprovedClanRequestsByCharacter = $"""
SELECT req."clan_id", req."requester_character_id", req."created", req."approved", chara."first_name", chara."last_name", param."name"
FROM ddon_clan_requests AS req
INNER JOIN ddon_character AS chara ON req.requester_character_id = chara.character_id
INNER JOIN ddon_clan_param AS param ON param.clan_id = req.clan_id
WHERE req.requester_character_id = @requester_character_id
AND req.approved = 1;
""";

private readonly string SqlSelectClanRequestsByClan = $"""
SELECT req."clan_id", req."requester_character_id", req."created", req."approved", chara."first_name", chara."last_name", param."name"
FROM ddon_clan_requests AS req
INNER JOIN ddon_character AS chara ON req.requester_character_id = chara.character_id
INNER JOIN ddon_clan_param AS param ON param.clan_id = req.clan_id
WHERE req.clan_id = @clan_id
AND req.approved = 0;
""";

private readonly string SqlSetClanRequestApproved = $"""
UPDATE ddon_clan_requests
SET approved = 1
WHERE requester_character_id = @requester_character_id;
""";

private readonly string SqlDeleteClanRequestByCharacter = $"""
DELETE FROM ddon_clan_requests
WHERE requester_character_id = @requester_character_id;
""";

private readonly string SqlDeleteOldClanRequests = $"""
DELETE FROM ddon_clan_requests
WHERE created < @date_filter;
""";


public override bool InsertClanRequest(uint clanId, uint characterId, DbConnection connectionIn = null)
{
return ExecuteQuerySafe(connectionIn, connection =>
{
return ExecuteNonQuery(connection, SqlInsertClanRequest, command =>
{
AddParameter(command, "clan_id", clanId);
AddParameter(command, "requester_character_id", characterId);
AddParameter(command, "created", DateTime.Now);
AddParameter(command, "approved", 0);
}) == 1;
});
}

public override List<CDataClanJoinRequest> GetClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null)
{
List<CDataClanJoinRequest> results = new();
ExecuteQuerySafe(connectionIn, connection =>
{
ExecuteReader(connection, SqlSelectClanRequestsByCharacter, command =>
{
AddParameter(command, "requester_character_id", characterId);
},
reader =>
{
while (reader.Read())
{
results.Add(ReadClanRequestData(reader));
}
});
});

return results;
}
public override List<CDataClanJoinRequest> GetApprovedClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null)
{
List<CDataClanJoinRequest> results = new();
ExecuteQuerySafe(connectionIn, connection =>
{
ExecuteReader(connection, SqlSelectApprovedClanRequestsByCharacter, command =>
{
AddParameter(command, "requester_character_id", characterId);
},
reader =>
{
while (reader.Read())
{
results.Add(ReadClanRequestData(reader));
}
});
});

return results;
}

public override List<CDataClanJoinRequest> GetClanRequestsByClan(uint clanId, DbConnection? connectionIn = null)
{
List<CDataClanJoinRequest> results = new();
ExecuteQuerySafe(connectionIn, connection =>
{
ExecuteReader(connection, SqlSelectClanRequestsByClan, command =>
{
AddParameter(command, "clan_id", clanId);
},
reader =>
{
while (reader.Read())
{
results.Add(ReadClanRequestData(reader));
}
});
});

return results;
}

public override bool SetClanRequestApproved(uint characterId, DbConnection? connectionIn = null)
{
return ExecuteQuerySafe(connectionIn, connection =>
{
return ExecuteNonQuery(connection, SqlSetClanRequestApproved, command =>
{
AddParameter(command, "requester_character_id", characterId);
}) == 1;
});
}

public override bool DeleteClanRequestByCharacter(uint characterId, DbConnection? connectionIn = null)
{
return ExecuteQuerySafe(connectionIn, connection =>
{
return ExecuteNonQuery(connection, SqlDeleteClanRequestByCharacter, command =>
{
AddParameter(command, "requester_character_id", characterId);
}) == 1;
});
}

public override bool DeleteOldClanRequests(uint minDays = 30, DbConnection? connectionIn = null)
{
return ExecuteQuerySafe(connectionIn, connection =>
{
return ExecuteNonQuery(connection, SqlDeleteOldClanRequests, command =>
{
AddParameter(command, "date_filter", DateTime.Now.AddDays(-minDays));
}) == 1;
});
}

private CDataClanJoinRequest ReadClanRequestData(DbDataReader reader)
{
CDataClanJoinRequest result = new()
{
ClanId = GetUInt32(reader, "clan_id"),
ClanName = GetString(reader, "name"),
BaseInfo = new CDataCommunityCharacterBaseInfo()
{
CharacterId = GetUInt32(reader, "requester_character_id"),
CharacterName = new CDataCharacterName
{
FirstName = GetString(reader, "first_name"),
LastName = GetString(reader, "last_name")
}
},
CreateTime = GetDateTime(reader, "created")
};

return result;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Data.Common;

namespace Arrowgene.Ddon.Database.Sql.Core.Migration
{
public class ClanRequestMigration : IMigrationStrategy
{
public uint From => 43;
public uint To => 44;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may get bumped to 45 depending on the cadence of #822


private readonly DatabaseSetting DatabaseSetting;

public ClanRequestMigration(DatabaseSetting databaseSetting)
{
DatabaseSetting = databaseSetting;
}

public bool Migrate(IDatabase db, DbConnection conn)
{
string adaptedSchema = DdonDatabaseBuilder.GetAdaptedSchema(DatabaseSetting, "Script/migration_clan_requests.sql");
db.Execute(conn, adaptedSchema, true);
return true;
}
}
}
7 changes: 7 additions & 0 deletions Arrowgene.Ddon.Database/Sql/SqlDb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,13 @@ public abstract int UpdateContact(uint requestingCharacterId, uint requestedChar
public abstract List<CDataClanMemberInfo> GetClanMemberList(uint clanId, DbConnection? connectionIn = null);
public abstract CDataClanMemberInfo GetClanMember(uint characterId, DbConnection? connectionIn = null);
public abstract bool UpdateClanMember(CDataClanMemberInfo memberInfo, uint clanId, DbConnection? connectionIn = null);
public abstract bool InsertClanRequest(uint clanId, uint characterId, DbConnection? connectionIn = null);
public abstract List<CDataClanJoinRequest> GetClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

public abstract List<CDataClanJoinRequest> GetApprovedClanRequestsByCharacter(uint characterId, DbConnection? connectionIn = null);
public abstract List<CDataClanJoinRequest> GetClanRequestsByClan(uint clanId, DbConnection? connectionIn = null);
public abstract bool SetClanRequestApproved(uint characterId, DbConnection? connectionIn = null);
public abstract bool DeleteClanRequestByCharacter(uint characterId, DbConnection? connectionIn = null);
public abstract bool DeleteOldClanRequests(uint minDays = 30, DbConnection? connectionIn = null);
public abstract List<uint> SelectClanShopPurchases(uint clanId, DbConnection? connectionIn = null);
public abstract bool InsertClanShopPurchase(uint clanId, uint lineupId, DbConnection? connectionIn = null);
public abstract List<(byte Type, uint Id)> SelectClanBaseCustomizations(uint clanId, DbConnection? connectionIn = null);
Expand Down
Loading
Loading