Skip to content

Commit

Permalink
SQLite support - new default db method
Browse files Browse the repository at this point in the history
  • Loading branch information
RenderBr committed Oct 15, 2023
1 parent b88d663 commit 6a34d10
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 77 deletions.
161 changes: 124 additions & 37 deletions Supplier/Api/SupplierApi.cs
Original file line number Diff line number Diff line change
@@ -1,72 +1,159 @@
using Auxiliary;
using Auxiliary.Configuration;
using MongoDB.Driver;
using SQLite;
using Supplier.Models;
using Supplier.Models.Auxiliary;
using Supplier.Models.SQLite;
using Terraria;
using TShockAPI;

namespace Supplier.Api
{
public class SupplierApi
{
public SupplierApi()
{
// this is done to see if a connection can even be made to auxiliary
// it will also force Auxiliary to auto-gen a config
StorageProvider.GetMongoCollection<InfiniteChest>("InfiniteChests");
Console.WriteLine("SupplierAPI has connected to the database successfully.");
}

public string? WorldName { get; set; }
public SupplierApi() {}
private string dbPath = Path.Combine(TShock.SavePath, "supplier.sqlite");
public SupplierSettings Config { get; set; }
public static SQLiteAsyncConnection? SQL {get; set;}

#region Add Chest
public async void AddChest(Chest chest, int delay)
public async Task AddChest(Chest chest, int delay)
{
// add the chest to our database, marking it as infinite
await IModel.CreateAsync(CreateRequest.Bson<InfiniteChest>(x =>
int chestId = Main.chest.ToList().IndexOf(chest);

if (Config.DatabaseType != "sqlite")
{
// retrieve chest world index
x.Index = Main.chest.ToList().IndexOf(chest);
// add the chest to our database, marking it as infinite
await IModel.CreateAsync(CreateRequest.Bson<InfiniteChest>(x =>
{
x.ChestID = chestId;
x.X = chest.x;
x.Y = chest.y;
x.Delay = delay;
x.World = Main.worldName;

// retrieve chest coordinates
x.X = chest.x;
x.Y = chest.y;
// Create a list storing all the item slots and the respective item slot data
var items = chest.item.Select((item, index) =>
new ChestItem(item.type, item.stack, item.prefix, index)).ToList();

// set the delay, will be in miliseconds
x.Delay = delay;
x.Items = items;
}));
}
else
{
SQLInfiniteChest x = new SQLInfiniteChest()
{
ChestID = chestId,
X = chest.x,
Y = chest.y,
Delay = delay,
World = Main.worldName
};

// assign chests world
x.World = WorldName;
// Create a list storing all the item slots and the respective item slot data
var sqlChestItems = chest.item.Select((item, index) =>
new SQLChestItem(chestId, item.type, item.stack, item.prefix, index)).ToList();

// create a list storing all the item slots, and the respective item slot data
List<ChestItem> Items = new List<ChestItem>();
await SQL.InsertAllAsync(sqlChestItems);
await SQL.InsertAsync(x);
}
}

#endregion

// loop through each item in the existing chest
foreach (Item item in chest.item)
#region Retrieve Chest
public async Task<IInfiniteChest>? RetrieveChest(int _x, int _y)
{
IInfiniteChest? chest;
// retrieve the chest from the coordinates
if(Config.DatabaseType != "sqlite")
chest = await IModel.GetAsync(GetRequest.Bson<InfiniteChest>(x => x.X == _x && x.Y == _y && (x.World == Main.worldName || string.IsNullOrEmpty(x.World))));
else
{
var chestQuery = SQL.Table<SQLInfiniteChest>().Where(x => x.X == _x && x.Y == _y && (x.World == Main.worldName || string.IsNullOrEmpty(x.World)));
if (await chestQuery.CountAsync() > 0)
{
// and add each item to the list
Items.Add(new ChestItem(item.type, item.stack, item.prefix));
chest = await chestQuery.FirstAsync();
}
else
{
chest = null; // No matching data found
}
}

// add our new list to the database
x.Items = Items;
}));
// return the chest
return chest;
}
#endregion

#region Retrieve Chest
public async Task<InfiniteChest> RetrieveChest(int _x, int _y)
#region Retrieve Chest Items
public async Task<List<ChestItem>> RetrieveChestItems(int chestID)
{
// retrieve the chest from the coordinates
var entity = await IModel.GetAsync(GetRequest.Bson<InfiniteChest>(x => x.X == _x && x.Y == _y && (x.World == WorldName || string.IsNullOrEmpty(x.World))));
// return the chest
return entity;
List<ChestItem> chests = new List<ChestItem>();

if (Config.DatabaseType != "sqlite")
{
var infiniteChest = await IModel.GetAsync(GetRequest.Bson<InfiniteChest>(x => x.ChestID == chestID && (x.World == Main.worldName || string.IsNullOrEmpty(x.World))));
if (infiniteChest != null)
{
chests = infiniteChest.Items;
}
}
else
{
var chestItems = await SQL.Table<SQLChestItem>().Where(x => x.ChestId == chestID).ToListAsync();

if (chestItems.Count > 0)
{
chests.AddRange(chestItems.Select(ci => new ChestItem(ci.Type, ci.Stack, ci.PrefixID, ci.Slot)));
}
}

return chests;
}
#endregion

#region Remove Chest
public async void RemoveChest(int _x, int _y)
{
await StorageProvider.GetMongoCollection<InfiniteChest>("InfiniteChests").Find(x => x.X == _x && x.Y == _y && (x.World == WorldName || string.IsNullOrEmpty(x.World))).First().DeleteAsync();
if (Config.DatabaseType != "sqlite")
await StorageProvider.GetMongoCollection<InfiniteChest>("InfiniteChests").Find(x => x.X == _x && x.Y == _y && (x.World == Main.worldName || string.IsNullOrEmpty(x.World))).First().DeleteAsync();
else
{
var chestID = (await RetrieveChest(_x, _y)).ChestID;
await SQL.Table<SQLChestItem>().DeleteAsync(x=>x.ChestId==chestID);
await SQL.Table<SQLInfiniteChest>().DeleteAsync(x => x.X == _x && x.Y == _y && (x.World == Main.worldName || string.IsNullOrEmpty(x.World)));
}

}
#endregion

#region Reload Config
public async Task ReloadConfig() {
Config = Configuration<SupplierSettings>.Load(nameof(Supplier));

switch(Config.DatabaseType)
{
case "sqlite":
{
SQL = new SQLiteAsyncConnection(dbPath);
await SQL.CreateTableAsync<SQLInfiniteChest>();
await SQL.CreateTableAsync<SQLChestItem>();
Console.WriteLine("SupplierAPI has connected to the database successfully (via SQLite)");
break;

}
case "mongodb":
default:
{
StorageProvider.GetMongoCollection<InfiniteChest>("InfiniteChests");
Console.WriteLine("SupplierAPI has connected to the database successfully (via Auxiliary)");
break;
}
}
}

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
using Auxiliary;

namespace Supplier.Models
namespace Supplier.Models.Auxiliary
{
public class ChestItem : BsonModel
{
public int type;
public int stack;
public byte prefixID;
public int slot;

public ChestItem(int _type, int _stack, byte prefix)
public ChestItem(int _type, int _stack, byte prefix, int _slot)
{
type = _type;
stack = _stack;
prefixID = prefix;
slot = _slot;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using Auxiliary;
using Microsoft.Xna.Framework;

namespace Supplier.Models
namespace Supplier.Models.Auxiliary
{
public class InfiniteChest : BsonModel
public class InfiniteChest : BsonModel, IInfiniteChest
{
private int _index;
public int Index
private int _chestID;
public int ChestID
{
get
=> _index;
=> _chestID;
set
{
_ = this.SaveAsync(x => x.Index, value);
_index = value;
_ = this.SaveAsync(x => x.ChestID, value);
_chestID = value;
}
}

Expand Down Expand Up @@ -77,5 +78,8 @@ public int Delay
}
}

Vector2 IInfiniteChest.RetrievePosition() => new Vector2(X,Y);

List<ChestItem> RetrieveItems() => Items;
}
}
18 changes: 18 additions & 0 deletions Supplier/Models/IInfiniteChest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.Xna.Framework;
using Supplier.Models.Auxiliary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Supplier.Models
{
public interface IInfiniteChest
{
public abstract Vector2 RetrievePosition();
public int Delay { get; set; }
public int ChestID { get; set; }
public string World { get; set; }
}
}
39 changes: 39 additions & 0 deletions Supplier/Models/SQLite/SQLChestItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using SQLite;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Supplier.Models.SQLite
{
public class SQLChestItem
{
public SQLChestItem() { }
public SQLChestItem(int _cid, int _type, int _stack, byte prefix, int slot)
{
ChestId = _cid;
Type = _type;
Stack = _stack;
PrefixID = prefix;
Slot = slot;
}

[PrimaryKey, AutoIncrement]
public int Id { get; set; }

[ForeignKey("ChestId")]
public int ChestId { get; set; }


[Indexed]
public int Type { get; set; }
public int Stack { get; set; }
public byte PrefixID { get; set; }

public int Slot { get; set; }

}
}
25 changes: 25 additions & 0 deletions Supplier/Models/SQLite/SqlInfiniteChest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Auxiliary;
using Microsoft.Xna.Framework;
using SQLite;
using Supplier.Api;
using Supplier.Models.SQLite;
using Terraria;

namespace Supplier.Models.Auxiliary
{
public class SQLInfiniteChest : IInfiniteChest
{
[PrimaryKey, AutoIncrement]
public int Index { get; set; }
public int ChestID { get; set; }

[Indexed]
public string World { get; set; }
public int X { get; set; }
public int Y { get; set; }
public Vector2 RetrievePosition() => new Vector2(X, Y);
public int Delay { get; set; }


}
}
Loading

0 comments on commit 6a34d10

Please sign in to comment.