Holy SQL.
This commit is contained in:
parent
1ab0b01f43
commit
4f241917b6
68
NadekoBot/Classes/DBHandler.cs
Normal file
68
NadekoBot/Classes/DBHandler.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
using SQLite;
|
||||||
|
using NadekoBot.Classes._DataModels;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes {
|
||||||
|
class DBHandler {
|
||||||
|
private static readonly DBHandler _instance = new DBHandler();
|
||||||
|
public static DBHandler Instance => _instance;
|
||||||
|
|
||||||
|
private string _filePath { get; } = "data/nadekobot.sqlite";
|
||||||
|
|
||||||
|
static DBHandler() { }
|
||||||
|
public DBHandler() {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
_conn.CreateTable<Stats>();
|
||||||
|
_conn.CreateTable<Command>();
|
||||||
|
_conn.CreateTable<Announcement>();
|
||||||
|
_conn.CreateTable<Request>();
|
||||||
|
_conn.CreateTable<TypingArticle>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InsertData<T>(T o) where T : IDataModel {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
_conn.Insert(o, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UpdateData<T>(T o) where T : IDataModel {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
_conn.Update(o, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal List<T> GetAllRows<T>() where T : IDataModel, new() {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
return _conn.Table<T>().Where(t => true).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal T Delete<T>(int Id) where T : IDataModel, new() {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
var found = _conn.Table<T>().Where(t => t.Id == Id).FirstOrDefault();
|
||||||
|
if (found != null)
|
||||||
|
_conn.Delete<T>(found.Id);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an existing object or creates a new one
|
||||||
|
/// </summary>
|
||||||
|
internal void Save<T>(T o) where T : IDataModel, new() {
|
||||||
|
using (var _conn = new SQLiteConnection(_filePath)) {
|
||||||
|
var found = _conn.Table<T>().Where(t => t.Id == o.Id).FirstOrDefault();
|
||||||
|
if (found == null)
|
||||||
|
_conn.Insert(o, typeof(T));
|
||||||
|
else
|
||||||
|
_conn.Update(o, typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,9 @@ namespace NadekoBot
|
|||||||
Console.WriteLine("Logging enabled.");
|
Console.WriteLine("Logging enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeSpan GetUptime() =>
|
||||||
|
DateTime.Now - Process.GetCurrentProcess().StartTime;
|
||||||
|
|
||||||
public string GetUptimeString() {
|
public string GetUptimeString() {
|
||||||
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||||
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
return time.Days + " days, " + time.Hours + " hours, and " + time.Minutes + " minutes.";
|
||||||
@ -72,18 +75,22 @@ namespace NadekoBot
|
|||||||
|
|
||||||
private async Task StartCollecting() {
|
private async Task StartCollecting() {
|
||||||
while (true) {
|
while (true) {
|
||||||
await Task.Delay(new TimeSpan(1, 0, 0));
|
await Task.Delay(new TimeSpan(0, 30, 0));
|
||||||
try {
|
try {
|
||||||
var obj = new ParseObject("Stats");
|
var onlineUsers = await Task.Run(() => NadekoBot.client.Servers.Sum(x => x.Users.Count()));
|
||||||
obj["OnlineUsers"] = await Task.Run(() => NadekoBot.client.Servers.Sum(x => x.Users.Count()));
|
var realOnlineUsers = await Task.Run(() => NadekoBot.client.Servers
|
||||||
obj["RealOnlineUsers"] = await Task.Run(() => NadekoBot
|
|
||||||
.client.Servers
|
|
||||||
.Sum(x => x.Users.Where(u => u.Status == UserStatus.Online).Count()));
|
.Sum(x => x.Users.Where(u => u.Status == UserStatus.Online).Count()));
|
||||||
obj["ConnectedServers"] = NadekoBot.client.Servers.Count();
|
var connectedServers = NadekoBot.client.Servers.Count();
|
||||||
|
|
||||||
await obj.SaveAsync();
|
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.Stats {
|
||||||
|
OnlineUsers = onlineUsers,
|
||||||
|
RealOnlineUsers = realOnlineUsers,
|
||||||
|
Uptime = GetUptime(),
|
||||||
|
ConnectedServers = connectedServers,
|
||||||
|
DateAdded = DateTime.Now
|
||||||
|
});
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
Console.WriteLine("Parse exception in StartCollecting");
|
Console.WriteLine("DB Exception in stats collecting.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,22 +100,19 @@ namespace NadekoBot
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_commandsRan++;
|
_commandsRan++;
|
||||||
var obj = new ParseObject("CommandsRan");
|
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.Command {
|
||||||
|
ServerId = (long)e.Server.Id,
|
||||||
obj["ServerId"] = e.Server.Id;
|
ServerName = e.Server.Name,
|
||||||
obj["ServerName"] = e.Server.Name;
|
ChannelId = (long)e.Channel.Id,
|
||||||
|
ChannelName =e.Channel.Name,
|
||||||
obj["ChannelId"] = e.Channel.Id;
|
UserId = (long)e.User.Id,
|
||||||
obj["ChannelName"] = e.Channel.Name;
|
UserName = e.User.Name,
|
||||||
|
CommandName = e.Command.Text,
|
||||||
obj["UserId"] = e.User.Id;
|
DateAdded = DateTime.Now
|
||||||
obj["UserName"] = e.User.Name;
|
});
|
||||||
|
|
||||||
obj["CommandName"] = e.Command.Text;
|
|
||||||
obj.SaveAsync();
|
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
Console.WriteLine("Parse error in ran command.");
|
Console.WriteLine("Parse error in ran command.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
21
NadekoBot/Classes/_DataModels/AnnouncementModel.cs
Normal file
21
NadekoBot/Classes/_DataModels/AnnouncementModel.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class Announcement : IDataModel {
|
||||||
|
public long ServerId { get; set; } = 0;
|
||||||
|
public bool Greet { get; set; } = false;
|
||||||
|
public bool GreetPM { get; set; } = false;
|
||||||
|
public long GreetChannelId { get; set; } = 0;
|
||||||
|
public string GreetText { get; set; } = "Welcome %user%!";
|
||||||
|
public bool Bye { get; set; } = false;
|
||||||
|
public bool ByePM { get; set; } = false;
|
||||||
|
public long ByeChannelId { get; set; } = 0;
|
||||||
|
public string ByeText { get; set; } = "%user% has left the server.";
|
||||||
|
public DateTime DateAdded { get; set; } = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
19
NadekoBot/Classes/_DataModels/CommandModel.cs
Normal file
19
NadekoBot/Classes/_DataModels/CommandModel.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class Command : IDataModel {
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public long ServerId { get; set; }
|
||||||
|
public string ServerName { get; set; }
|
||||||
|
public long ChannelId { get; set; }
|
||||||
|
public string ChannelName { get; set; }
|
||||||
|
public string CommandName { get; set; }
|
||||||
|
public DateTime DateAdded { get; set; }
|
||||||
|
}
|
||||||
|
}
|
14
NadekoBot/Classes/_DataModels/IDataModel.cs
Normal file
14
NadekoBot/Classes/_DataModels/IDataModel.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class IDataModel {
|
||||||
|
[PrimaryKey, AutoIncrement]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public IDataModel() { }
|
||||||
|
}
|
||||||
|
}
|
17
NadekoBot/Classes/_DataModels/RequestModel.cs
Normal file
17
NadekoBot/Classes/_DataModels/RequestModel.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class Request : IDataModel {
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public string ServerName { get; set; }
|
||||||
|
public long ServerId { get; set; }
|
||||||
|
public string RequestText { get; set; }
|
||||||
|
public DateTime DateAdded { get; set; }
|
||||||
|
}
|
||||||
|
}
|
16
NadekoBot/Classes/_DataModels/StatsModel.cs
Normal file
16
NadekoBot/Classes/_DataModels/StatsModel.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class Stats : IDataModel {
|
||||||
|
public int ConnectedServers { get; set; }
|
||||||
|
public int OnlineUsers { get; set; }
|
||||||
|
public TimeSpan Uptime { get; set; }
|
||||||
|
public int RealOnlineUsers { get; set; }
|
||||||
|
public DateTime DateAdded { get; set; }
|
||||||
|
}
|
||||||
|
}
|
13
NadekoBot/Classes/_DataModels/TypingArticleModel.cs
Normal file
13
NadekoBot/Classes/_DataModels/TypingArticleModel.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using SQLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Classes._DataModels {
|
||||||
|
class TypingArticle : IDataModel {
|
||||||
|
public string Text { get; set; }
|
||||||
|
public DateTime DateAdded { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,76 +1,42 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Parse;
|
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
|
||||||
namespace NadekoBot.Commands {
|
namespace NadekoBot.Commands {
|
||||||
class RequestsCommand : DiscordCommand {
|
class RequestsCommand : DiscordCommand {
|
||||||
public void SaveRequest(CommandEventArgs e, string text) {
|
public void SaveRequest(CommandEventArgs e, string text) {
|
||||||
|
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.Request {
|
||||||
var obj = new ParseObject("Requests");
|
RequestText = text,
|
||||||
|
UserName = e.User.Name,
|
||||||
obj["ServerId"] = e.Server.Id;
|
UserId = (long)e.User.Id,
|
||||||
obj["ServerName"] = e.Server.Name;
|
ServerId = (long)e.Server.Id,
|
||||||
obj["UserId"] = e.User.Id;
|
ServerName = e.Server.Name,
|
||||||
obj["UserName"] = e.User.Name;
|
DateAdded = DateTime.Now
|
||||||
obj["Request"] = text;
|
});
|
||||||
|
|
||||||
obj.SaveAsync();
|
|
||||||
}
|
}
|
||||||
// todo what if it's too long?
|
// todo what if it's too long?
|
||||||
public string GetRequests() {
|
public string GetRequests() {
|
||||||
var task = ParseObject.GetQuery("Requests")
|
var task = Classes.DBHandler.Instance.GetAllRows<Classes._DataModels.Request>();
|
||||||
.FindAsync().Result;
|
|
||||||
|
|
||||||
string str = "Here are all current requests for NadekoBot:\n\n";
|
string str = "Here are all current requests for NadekoBot:\n\n";
|
||||||
int i = 1;
|
int i = 1;
|
||||||
foreach (var reqObj in task) {
|
foreach (var reqObj in task) {
|
||||||
str += (i++) + ". by **" + reqObj["UserName"] + "** from **" + reqObj["ServerName"] + "** at " + reqObj.CreatedAt.Value.ToLocalTime() + "\n";
|
str += $"{reqObj.Id}. by **{reqObj.UserName}** from **{reqObj.ServerName}** at {reqObj.DateAdded.ToLocalTime()}\n" +
|
||||||
str += "**" + reqObj["Request"] + "**\n----------\n";
|
$"**{reqObj.RequestText}**\n----------\n";
|
||||||
}
|
}
|
||||||
return str + "\n__Type [@NadekoBot clr] to clear all of my messages.__";
|
return str + "\n__Type [@NadekoBot clr] to clear all of my messages.__";
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteRequest(int requestNumber) {
|
public bool DeleteRequest(int requestNumber) =>
|
||||||
var task = ParseObject.GetQuery("Requests")
|
Classes.DBHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber) != null;
|
||||||
.FindAsync().Result;
|
|
||||||
int i = 1;
|
|
||||||
foreach (var reqObj in task) {
|
|
||||||
if (i == requestNumber) {
|
|
||||||
reqObj.DeleteAsync();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ResolveRequestObject {
|
|
||||||
public ulong Id;
|
|
||||||
public ulong ServerId;
|
|
||||||
public string Text;
|
|
||||||
}
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a request with a number and returns that users id.
|
/// Delete a request with a number and returns that request object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>RequestObject of the request. Null if none</returns>
|
/// <returns>RequestObject of the request. Null if none</returns>
|
||||||
public ResolveRequestObject ResolveRequest(int requestNumber) {
|
public Classes._DataModels.Request ResolveRequest(int requestNumber) =>
|
||||||
var task = ParseObject.GetQuery("Requests")
|
Classes.DBHandler.Instance.Delete<Classes._DataModels.Request>(requestNumber);
|
||||||
.FindAsync().Result;
|
|
||||||
int i = 1;
|
|
||||||
foreach (var reqObj in task) {
|
|
||||||
if (i == requestNumber) {
|
|
||||||
var txt = reqObj.Get<string>("Request");
|
|
||||||
var id = reqObj.Get<ulong>("UserId");
|
|
||||||
var sid = reqObj.Get<ulong>("ServerId");
|
|
||||||
reqObj.DeleteAsync();
|
|
||||||
return new ResolveRequestObject { Id = id, Text = txt, ServerId = sid };
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Func<CommandEventArgs, Task> DoFunc() {
|
public override Func<CommandEventArgs, Task> DoFunc() {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -130,7 +96,7 @@ namespace NadekoBot.Commands {
|
|||||||
var sc = ResolveRequest(int.Parse(e.Args[0]));
|
var sc = ResolveRequest(int.Parse(e.Args[0]));
|
||||||
if (sc != null) {
|
if (sc != null) {
|
||||||
await e.Send(e.User.Mention + " Request resolved, notice sent.");
|
await e.Send(e.User.Mention + " Request resolved, notice sent.");
|
||||||
await client.GetServer(sc.ServerId).GetUser(sc.Id).Send("**This request of yours has been resolved:**\n" + sc.Text);
|
await client.GetServer((ulong)sc.ServerId).GetUser((ulong)sc.UserId).Send("**This request of yours has been resolved:**\n" + sc.RequestText);
|
||||||
} else {
|
} else {
|
||||||
await e.Send("No request on that number.");
|
await e.Send("No request on that number.");
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,11 @@ namespace NadekoBot.Commands {
|
|||||||
NadekoBot.client.UserJoined += UserJoined;
|
NadekoBot.client.UserJoined += UserJoined;
|
||||||
NadekoBot.client.UserLeft += UserLeft;
|
NadekoBot.client.UserLeft += UserLeft;
|
||||||
|
|
||||||
var data = new ParseQuery<ParseObject>("Announcements")
|
List<Classes._DataModels.Announcement> data = Classes.DBHandler.Instance.GetAllRows<Classes._DataModels.Announcement>();
|
||||||
.FindAsync()
|
|
||||||
.Result;
|
|
||||||
if (data.Any())
|
if (data.Any())
|
||||||
foreach (var po in data)
|
foreach (var obj in data)
|
||||||
AnnouncementsDictionary.TryAdd(po.Get<ulong>("serverId"), new AnnounceControls(po.Get<ulong>("serverId")).Initialize(po));
|
AnnouncementsDictionary.TryAdd((ulong)obj.ServerId, new AnnounceControls(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UserLeft(object sender, UserEventArgs e) {
|
private async void UserLeft(object sender, UserEventArgs e) {
|
||||||
@ -85,67 +84,59 @@ namespace NadekoBot.Commands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class AnnounceControls {
|
public class AnnounceControls {
|
||||||
private ParseObject ParseObj = null;
|
private Classes._DataModels.Announcement _model { get; }
|
||||||
|
|
||||||
private bool greet;
|
|
||||||
|
|
||||||
public bool Greet {
|
public bool Greet {
|
||||||
get { return greet; }
|
get { return _model.Greet; }
|
||||||
set { greet = value; Save(); }
|
set { _model.Greet = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong greetChannel;
|
|
||||||
|
|
||||||
public ulong GreetChannel {
|
public ulong GreetChannel {
|
||||||
get { return greetChannel; }
|
get { return (ulong)_model.GreetChannelId; }
|
||||||
set { greetChannel = value; }
|
set { _model.GreetChannelId = (long)value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool greetPM;
|
|
||||||
|
|
||||||
public bool GreetPM {
|
public bool GreetPM {
|
||||||
get { return greetPM; }
|
get { return _model.GreetPM; }
|
||||||
set { greetPM = value; Save(); }
|
set { _model.GreetPM = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool byePM;
|
|
||||||
|
|
||||||
public bool ByePM {
|
public bool ByePM {
|
||||||
get { return byePM; }
|
get { return _model.ByePM; }
|
||||||
set { byePM = value; Save(); }
|
set { _model.ByePM = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private string greetText = "Welcome to the server %user%";
|
|
||||||
public string GreetText {
|
public string GreetText {
|
||||||
get { return greetText; }
|
get { return _model.GreetText; }
|
||||||
set { greetText = value; Save(); }
|
set { _model.GreetText = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool bye;
|
|
||||||
|
|
||||||
public bool Bye {
|
public bool Bye {
|
||||||
get { return bye; }
|
get { return _model.Bye; }
|
||||||
set { bye = value; Save(); }
|
set { _model.Bye = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong byeChannel;
|
|
||||||
|
|
||||||
public ulong ByeChannel {
|
public ulong ByeChannel {
|
||||||
get { return byeChannel; }
|
get { return (ulong)_model.ByeChannelId; }
|
||||||
set { byeChannel = value; }
|
set { _model.ByeChannelId = (long)value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private string byeText = "%user% has left the server";
|
|
||||||
public string ByeText {
|
public string ByeText {
|
||||||
get { return byeText; }
|
get { return _model.ByeText; }
|
||||||
set { byeText = value; Save(); }
|
set { _model.ByeText = value; Save(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ulong ServerId {
|
||||||
public ulong ServerId { get; }
|
get { return (ulong)_model.ServerId; }
|
||||||
|
set { _model.ServerId = (long)value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnnounceControls(Classes._DataModels.Announcement model) {
|
||||||
|
this._model = model;
|
||||||
|
}
|
||||||
|
|
||||||
public AnnounceControls(ulong serverId) {
|
public AnnounceControls(ulong serverId) {
|
||||||
this.ServerId = serverId;
|
this._model = new Classes._DataModels.Announcement();
|
||||||
|
ServerId = serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ToggleBye(ulong id) {
|
internal bool ToggleBye(ulong id) {
|
||||||
@ -169,39 +160,7 @@ namespace NadekoBot.Commands {
|
|||||||
internal bool ToggleByePM() => ByePM = !ByePM;
|
internal bool ToggleByePM() => ByePM = !ByePM;
|
||||||
|
|
||||||
private void Save() {
|
private void Save() {
|
||||||
ParseObject p = null;
|
Classes.DBHandler.Instance.Save(_model);
|
||||||
if (this.ParseObj != null)
|
|
||||||
p = ParseObj;
|
|
||||||
else
|
|
||||||
p = ParseObj = new ParseObject("Announcements");
|
|
||||||
p["greet"] = greet;
|
|
||||||
p["greetPM"] = greetPM;
|
|
||||||
p["greetText"] = greetText;
|
|
||||||
p["greetChannel"] = greetChannel;
|
|
||||||
|
|
||||||
p["bye"] = bye;
|
|
||||||
p["byePM"] = byePM;
|
|
||||||
p["byeText"] = byeText;
|
|
||||||
p["byeChannel"] = byeChannel;
|
|
||||||
|
|
||||||
p["serverId"] = ServerId;
|
|
||||||
|
|
||||||
p.SaveAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal AnnounceControls Initialize(ParseObject po) {
|
|
||||||
greet = po.Get<bool>("greet");
|
|
||||||
greetPM = po.ContainsKey("greetPM") ? po.Get<bool>("greetPM") : false;
|
|
||||||
greetText = po.Get<string>("greetText");
|
|
||||||
greetChannel = po.Get<ulong>("greetChannel");
|
|
||||||
|
|
||||||
bye = po.Get<bool>("bye");
|
|
||||||
byePM = po.ContainsKey("byePM") ? po.Get<bool>("byePM") : false;
|
|
||||||
byeText = po.Get<string>("byeText");
|
|
||||||
byeChannel = po.Get<ulong>("byeChannel");
|
|
||||||
|
|
||||||
this.ParseObj = po;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +227,7 @@ namespace NadekoBot.Commands {
|
|||||||
AnnouncementsDictionary[e.Server.Id].ByeText = e.GetArg("msg");
|
AnnouncementsDictionary[e.Server.Id].ByeText = e.GetArg("msg");
|
||||||
await e.Send("New bye message set.");
|
await e.Send("New bye message set.");
|
||||||
if (!AnnouncementsDictionary[e.Server.Id].Bye)
|
if (!AnnouncementsDictionary[e.Server.Id].Bye)
|
||||||
await e.Send("Enable bye messsages by typing `.bye`, and set the bye message using `.byemsg`");
|
await e.Send("Enable bye messsages by typing `.bye`.");
|
||||||
});
|
});
|
||||||
|
|
||||||
cgb.CreateCommand(".byepm")
|
cgb.CreateCommand(".byepm")
|
||||||
|
@ -151,13 +151,13 @@ namespace NadekoBot.Commands {
|
|||||||
cgb.CreateCommand("typeadd")
|
cgb.CreateCommand("typeadd")
|
||||||
.Description("Adds a new article to the typing contest. Owner only.")
|
.Description("Adds a new article to the typing contest. Owner only.")
|
||||||
.Parameter("text",ParameterType.Unparsed)
|
.Parameter("text",ParameterType.Unparsed)
|
||||||
.Do(async e => {
|
.Do(e => {
|
||||||
if (e.User.Id != NadekoBot.OwnerID || e.GetArg("text") == null) return;
|
if (e.User.Id != NadekoBot.OwnerID || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
||||||
|
|
||||||
var obj = new ParseObject("TypingArticles");
|
Classes.DBHandler.Instance.InsertData(new Classes._DataModels.TypingArticle {
|
||||||
obj["text"] = e.GetArg("text");
|
Text = e.GetArg("text"),
|
||||||
await obj.SaveAsync();
|
DateAdded = DateTime.Now
|
||||||
await e.Send("Added new typing article.");
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo add user submissions
|
//todo add user submissions
|
||||||
|
@ -173,4 +173,6 @@ namespace NadekoBot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//95520984584429568 meany
|
@ -30,6 +30,8 @@
|
|||||||
<UseApplicationTrust>false</UseApplicationTrust>
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -40,6 +42,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -127,16 +130,21 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Classes\DBHandler.cs" />
|
||||||
<Compile Include="Classes\Music\MusicControls.cs" />
|
<Compile Include="Classes\Music\MusicControls.cs" />
|
||||||
<Compile Include="Classes\Music\StreamRequest.cs" />
|
<Compile Include="Classes\Music\StreamRequest.cs" />
|
||||||
<Compile Include="Classes\Music\SoundCloud.cs" />
|
<Compile Include="Classes\Music\SoundCloud.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\AnnouncementModel.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\CommandModel.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\IDataModel.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\RequestModel.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\StatsModel.cs" />
|
||||||
|
<Compile Include="Classes\_DataModels\TypingArticleModel.cs" />
|
||||||
<Compile Include="Commands\TriviaCommand.cs" />
|
<Compile Include="Commands\TriviaCommand.cs" />
|
||||||
<Compile Include="Classes\Trivia\TriviaGame.cs" />
|
<Compile Include="Classes\Trivia\TriviaGame.cs" />
|
||||||
<Compile Include="Classes\Trivia\TriviaQuestion.cs" />
|
<Compile Include="Classes\Trivia\TriviaQuestion.cs" />
|
||||||
@ -153,6 +161,7 @@
|
|||||||
<Compile Include="Commands\DrawCommand.cs" />
|
<Compile Include="Commands\DrawCommand.cs" />
|
||||||
<Compile Include="Commands\FlipCoinCommand.cs" />
|
<Compile Include="Commands\FlipCoinCommand.cs" />
|
||||||
<Compile Include="Commands\HelpCommand.cs" />
|
<Compile Include="Commands\HelpCommand.cs" />
|
||||||
|
<Compile Include="Commands\VoiceNotificationCommand.cs" />
|
||||||
<Compile Include="Modules\Administration.cs" />
|
<Compile Include="Modules\Administration.cs" />
|
||||||
<Compile Include="Modules\Conversations.cs" />
|
<Compile Include="Modules\Conversations.cs" />
|
||||||
<Compile Include="Modules\DiscordModule.cs" />
|
<Compile Include="Modules\DiscordModule.cs" />
|
||||||
@ -170,6 +179,8 @@
|
|||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Classes\NadekoStats.cs" />
|
<Compile Include="Classes\NadekoStats.cs" />
|
||||||
|
<Compile Include="SQLite.cs" />
|
||||||
|
<Compile Include="SQLiteAsync.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
|
3278
NadekoBot/SQLite.cs
Normal file
3278
NadekoBot/SQLite.cs
Normal file
File diff suppressed because it is too large
Load Diff
503
NadekoBot/SQLiteAsync.cs
Normal file
503
NadekoBot/SQLiteAsync.cs
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Krueger Systems, Inc.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SQLite
|
||||||
|
{
|
||||||
|
public partial class SQLiteAsyncConnection
|
||||||
|
{
|
||||||
|
SQLiteConnectionString _connectionString;
|
||||||
|
SQLiteOpenFlags _openFlags;
|
||||||
|
|
||||||
|
public SQLiteAsyncConnection(string databasePath, bool storeDateTimeAsTicks = false)
|
||||||
|
: this(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLiteAsyncConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false)
|
||||||
|
{
|
||||||
|
_openFlags = openFlags;
|
||||||
|
_connectionString = new SQLiteConnectionString(databasePath, storeDateTimeAsTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLiteConnectionWithLock GetConnection ()
|
||||||
|
{
|
||||||
|
return SQLiteConnectionPool.Shared.GetConnection (_connectionString, _openFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTableAsync<T> ()
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
return CreateTablesAsync (typeof (T));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTablesAsync<T, T2> ()
|
||||||
|
where T : new ()
|
||||||
|
where T2 : new ()
|
||||||
|
{
|
||||||
|
return CreateTablesAsync (typeof (T), typeof (T2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> ()
|
||||||
|
where T : new ()
|
||||||
|
where T2 : new ()
|
||||||
|
where T3 : new ()
|
||||||
|
{
|
||||||
|
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> ()
|
||||||
|
where T : new ()
|
||||||
|
where T2 : new ()
|
||||||
|
where T3 : new ()
|
||||||
|
where T4 : new ()
|
||||||
|
{
|
||||||
|
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> ()
|
||||||
|
where T : new ()
|
||||||
|
where T2 : new ()
|
||||||
|
where T3 : new ()
|
||||||
|
where T4 : new ()
|
||||||
|
where T5 : new ()
|
||||||
|
{
|
||||||
|
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<CreateTablesResult> CreateTablesAsync (params Type[] types)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
CreateTablesResult result = new CreateTablesResult ();
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
foreach (Type type in types) {
|
||||||
|
int aResult = conn.CreateTable (type);
|
||||||
|
result.Results[type] = aResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> DropTableAsync<T> ()
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.DropTable<T> ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> InsertAsync (object item)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Insert (item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> UpdateAsync (object item)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Update (item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> DeleteAsync (object item)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Delete (item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> GetAsync<T>(object pk)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
var conn = GetConnection();
|
||||||
|
using (conn.Lock())
|
||||||
|
{
|
||||||
|
return conn.Get<T>(pk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> FindAsync<T> (object pk)
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Find<T> (pk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
var conn = GetConnection();
|
||||||
|
using (conn.Lock())
|
||||||
|
{
|
||||||
|
return conn.Get<T> (predicate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate)
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Find<T> (predicate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> ExecuteAsync (string query, params object[] args)
|
||||||
|
{
|
||||||
|
return Task<int>.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Execute (query, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> InsertAllAsync (IEnumerable items)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.InsertAll (items);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> UpdateAllAsync (IEnumerable items)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.UpdateAll (items);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("Will cause a deadlock if any call in action ends up in a different thread. Use RunInTransactionAsync(Action<SQLiteConnection>) instead.")]
|
||||||
|
public Task RunInTransactionAsync (Action<SQLiteAsyncConnection> action)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
var conn = this.GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
conn.BeginTransaction ();
|
||||||
|
try {
|
||||||
|
action (this);
|
||||||
|
conn.Commit ();
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
conn.Rollback ();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task RunInTransactionAsync(Action<SQLiteConnection> action)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
var conn = this.GetConnection();
|
||||||
|
using (conn.Lock())
|
||||||
|
{
|
||||||
|
conn.BeginTransaction();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action(conn);
|
||||||
|
conn.Commit();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
conn.Rollback();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> Table<T> ()
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// This isn't async as the underlying connection doesn't go out to the database
|
||||||
|
// until the query is performed. The Async methods are on the query iteself.
|
||||||
|
//
|
||||||
|
var conn = GetConnection ();
|
||||||
|
return new AsyncTableQuery<T> (conn.Table<T> ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> ExecuteScalarAsync<T> (string sql, params object[] args)
|
||||||
|
{
|
||||||
|
return Task<T>.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
var command = conn.CreateCommand (sql, args);
|
||||||
|
return command.ExecuteScalar<T> ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<List<T>> QueryAsync<T> (string sql, params object[] args)
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
return Task<List<T>>.Factory.StartNew (() => {
|
||||||
|
var conn = GetConnection ();
|
||||||
|
using (conn.Lock ()) {
|
||||||
|
return conn.Query<T> (sql, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Bind to AsyncConnection.GetConnection instead so that delayed
|
||||||
|
// execution can still work after a Pool.Reset.
|
||||||
|
//
|
||||||
|
public class AsyncTableQuery<T>
|
||||||
|
where T : new ()
|
||||||
|
{
|
||||||
|
TableQuery<T> _innerQuery;
|
||||||
|
|
||||||
|
public AsyncTableQuery (TableQuery<T> innerQuery)
|
||||||
|
{
|
||||||
|
_innerQuery = innerQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> Where (Expression<Func<T, bool>> predExpr)
|
||||||
|
{
|
||||||
|
return new AsyncTableQuery<T> (_innerQuery.Where (predExpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> Skip (int n)
|
||||||
|
{
|
||||||
|
return new AsyncTableQuery<T> (_innerQuery.Skip (n));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> Take (int n)
|
||||||
|
{
|
||||||
|
return new AsyncTableQuery<T> (_innerQuery.Take (n));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr)
|
||||||
|
{
|
||||||
|
return new AsyncTableQuery<T> (_innerQuery.OrderBy<U> (orderExpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncTableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr)
|
||||||
|
{
|
||||||
|
return new AsyncTableQuery<T> (_innerQuery.OrderByDescending<U> (orderExpr));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<List<T>> ToListAsync ()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||||
|
return _innerQuery.ToList ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> CountAsync ()
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||||
|
return _innerQuery.Count ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> ElementAtAsync (int index)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew (() => {
|
||||||
|
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||||
|
return _innerQuery.ElementAt (index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> FirstAsync ()
|
||||||
|
{
|
||||||
|
return Task<T>.Factory.StartNew(() => {
|
||||||
|
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||||
|
return _innerQuery.First ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T> FirstOrDefaultAsync ()
|
||||||
|
{
|
||||||
|
return Task<T>.Factory.StartNew(() => {
|
||||||
|
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||||
|
return _innerQuery.FirstOrDefault ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateTablesResult
|
||||||
|
{
|
||||||
|
public Dictionary<Type, int> Results { get; private set; }
|
||||||
|
|
||||||
|
internal CreateTablesResult ()
|
||||||
|
{
|
||||||
|
this.Results = new Dictionary<Type, int> ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SQLiteConnectionPool
|
||||||
|
{
|
||||||
|
class Entry
|
||||||
|
{
|
||||||
|
public SQLiteConnectionString ConnectionString { get; private set; }
|
||||||
|
public SQLiteConnectionWithLock Connection { get; private set; }
|
||||||
|
|
||||||
|
public Entry (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||||
|
{
|
||||||
|
ConnectionString = connectionString;
|
||||||
|
Connection = new SQLiteConnectionWithLock (connectionString, openFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnApplicationSuspended ()
|
||||||
|
{
|
||||||
|
Connection.Dispose ();
|
||||||
|
Connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry> ();
|
||||||
|
readonly object _entriesLock = new object ();
|
||||||
|
|
||||||
|
static readonly SQLiteConnectionPool _shared = new SQLiteConnectionPool ();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the singleton instance of the connection tool.
|
||||||
|
/// </summary>
|
||||||
|
public static SQLiteConnectionPool Shared
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _shared;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLiteConnectionWithLock GetConnection (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||||
|
{
|
||||||
|
lock (_entriesLock) {
|
||||||
|
Entry entry;
|
||||||
|
string key = connectionString.ConnectionString;
|
||||||
|
|
||||||
|
if (!_entries.TryGetValue (key, out entry)) {
|
||||||
|
entry = new Entry (connectionString, openFlags);
|
||||||
|
_entries[key] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.Connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes all connections managed by this pool.
|
||||||
|
/// </summary>
|
||||||
|
public void Reset ()
|
||||||
|
{
|
||||||
|
lock (_entriesLock) {
|
||||||
|
foreach (var entry in _entries.Values) {
|
||||||
|
entry.OnApplicationSuspended ();
|
||||||
|
}
|
||||||
|
_entries.Clear ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call this method when the application is suspended.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Behaviour here is to close any open connections.</remarks>
|
||||||
|
public void ApplicationSuspended ()
|
||||||
|
{
|
||||||
|
Reset ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SQLiteConnectionWithLock : SQLiteConnection
|
||||||
|
{
|
||||||
|
readonly object _lockPoint = new object ();
|
||||||
|
|
||||||
|
public SQLiteConnectionWithLock (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||||
|
: base (connectionString.DatabasePath, openFlags, connectionString.StoreDateTimeAsTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDisposable Lock ()
|
||||||
|
{
|
||||||
|
return new LockWrapper (_lockPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LockWrapper : IDisposable
|
||||||
|
{
|
||||||
|
object _lockPoint;
|
||||||
|
|
||||||
|
public LockWrapper (object lockPoint)
|
||||||
|
{
|
||||||
|
_lockPoint = lockPoint;
|
||||||
|
Monitor.Enter (_lockPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
Monitor.Exit (_lockPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@
|
|||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
||||||
<package id="Parse" version="1.6.2" targetFramework="net452" />
|
<package id="Parse" version="1.6.2" targetFramework="net452" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
||||||
|
<package id="sqlite-net" version="1.0.8" targetFramework="net452" />
|
||||||
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
||||||
<package id="VideoLibrary" version="1.3.3" targetFramework="net452" />
|
<package id="VideoLibrary" version="1.3.3" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue
Block a user