Skip to content
Merged
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
Binary file added Program/Demo.db
Binary file not shown.
20 changes: 10 additions & 10 deletions Program/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using Npgsql;
using System.Data;
using Dapper;
using System.Data.SQLite;
using Sqlkata.Compilers;

namespace Program
{
Expand All @@ -36,19 +38,17 @@ static void Main(string[] args)
"Server=tcp:localhost,1433;Initial Catalog=Lite;User ID=sa;Password=P@ssw0rd"
);

var db = new QueryFactory(connection, new SqlServerCompiler
{
UseLegacyPagination = true
});
// SQLiteConnection.CreateFile("Demo.db");

connection = new SQLiteConnection("Data Source=Demo.db");

var db = new QueryFactory(connection, new SqliteCompiler());

// db.Statement("create table accounts(id integer primary key,name text,currency_id text);");

db.Logger = q => Console.WriteLine(q.ToString());

var accounts = db.Query("Accounts")
.ForPage(2, 10)
.WhereRaw("[CurrencyId] in (?)", new object[] { 11 })
.WhereRaw("[CurrencyId] in (?)", new[] { 1, 2, 3 })
.WhereRaw("[CurrencyId] in (?)", new[] { "100", "200" })
.Get();
var accounts = db.Query("Accounts").OrderByDesc("Id").Offset(10).Get();

Console.WriteLine(JsonConvert.SerializeObject(accounts));

Expand Down
1 change: 1 addition & 0 deletions Program/Program.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Npgsql" Version="4.0.4" />
<PackageReference Include="System.Data.SqlClient" Version="4.5.1" />
<PackageReference Include="System.Data.SQLite" Version="1.0.109.2" />
</ItemGroup>

<PropertyGroup>
Expand Down
53 changes: 53 additions & 0 deletions QueryBuilder.Tests/SqliteLimitTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Sqlkata.Compilers;
using SqlKata;
using Xunit;

namespace SqlKata.Tests
{
public class SqliteLimitTest
{
private SqliteCompiler compiler = new SqliteCompiler();

[Fact]
public void WithNoLimitNorOffset()
{
var query = new Query("Table");
var ctx = new SqlResult { Query = query };

Assert.Null(compiler.CompileLimit(ctx));
}

[Fact]
public void WithNoOffset()
{
var query = new Query("Table").Limit(10);
var ctx = new SqlResult { Query = query };

Assert.Equal("LIMIT ?", compiler.CompileLimit(ctx));
Assert.Equal(10, ctx.Bindings[0]);
}

[Fact]
public void WithNoLimit()
{
var query = new Query("Table").Offset(20);
var ctx = new SqlResult { Query = query };

Assert.Equal("LIMIT -1 OFFSET ?", compiler.CompileLimit(ctx));
Assert.Equal(20, ctx.Bindings[0]);
Assert.Single(ctx.Bindings);
}

[Fact]
public void WithLimitAndOffset()
{
var query = new Query("Table").Limit(5).Offset(20);
var ctx = new SqlResult { Query = query };

Assert.Equal("LIMIT ? OFFSET ?", compiler.CompileLimit(ctx));
Assert.Equal(5, ctx.Bindings[0]);
Assert.Equal(20, ctx.Bindings[1]);
Assert.Equal(2, ctx.Bindings.Count);
}
}
}
17 changes: 9 additions & 8 deletions QueryBuilder/Compilers/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@ namespace SqlKata.Compilers
public abstract partial class Compiler
{
private readonly ConditionsCompilerProvider _compileConditionMethodsProvider;
protected string parameterPlaceholder = "?";
protected string parameterPlaceholderPrefix = "@p";
protected virtual string parameterPlaceholder { get; set; } = "?";
protected virtual string parameterPlaceholderPrefix { get; set; } = "@p";
protected virtual string OpeningIdentifier { get; set; } = "\"";
protected virtual string ClosingIdentifier { get; set; } = "\"";
protected virtual string ColumnAsKeyword { get; set; } = "AS ";
protected virtual string TableAsKeyword { get; set; } = "AS ";
protected virtual string LastId { get; set; } = "";

protected Compiler()
{
_compileConditionMethodsProvider = new ConditionsCompilerProvider(this);
}

public abstract string EngineCode { get; }
protected string OpeningIdentifier = "\"";
protected string ClosingIdentifier = "\"";
protected string ColumnAsKeyword = "AS ";
protected string TableAsKeyword = "AS ";
protected string LastId = "";


/// <summary>
/// A list of white-listed operators
Expand Down Expand Up @@ -588,7 +589,7 @@ public virtual string CompileOrders(SqlResult ctx)
return "ORDER BY " + string.Join(", ", columns);
}

public string CompileHaving(SqlResult ctx)
public virtual string CompileHaving(SqlResult ctx)
{
if (!ctx.Query.HasComponent("having", EngineCode))
{
Expand Down
2 changes: 2 additions & 0 deletions QueryBuilder/Compilers/SqlServerCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ protected override SqlResult CompileSelectQuery(Query query)
{
query.Select("*");
}

var order = CompileOrders(ctx) ?? "ORDER BY (SELECT 0)";

query.SelectRaw($"ROW_NUMBER() OVER ({order}) AS [row_num]", ctx.Bindings.ToArray());

query.ClearComponent("order");
Expand Down
80 changes: 80 additions & 0 deletions QueryBuilder/Compilers/SqliteCompiler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using SqlKata;
using SqlKata.Compilers;

namespace Sqlkata.Compilers
{
public class SqliteCompiler : Compiler
{
public override string EngineCode => "sqlite";
protected override string parameterPlaceholder { get; set; } = "?";
protected override string parameterPlaceholderPrefix { get; set; } = "@p";
protected override string OpeningIdentifier { get; set; } = "\"";
protected override string ClosingIdentifier { get; set; } = "\"";
protected override string LastId { get; set; } = "last_insert_rowid()";

public override string CompileTrue()
{
return "1";
}

public override string CompileFalse()
{
return "0";
}

public override string CompileLimit(SqlResult ctx)
{
var limit = ctx.Query.GetLimit(EngineCode);
var offset = ctx.Query.GetOffset(EngineCode);

if (limit == 0 && offset > 0)
{
ctx.Bindings.Add(offset);
return "LIMIT -1 OFFSET ?";
}

return base.CompileLimit(ctx);
}

protected override string CompileBasicDateCondition(SqlResult ctx, BasicDateCondition condition)
{
var column = Wrap(condition.Column);
var value = Parameter(ctx, condition.Value);

var formatMap = new Dictionary<string, string> {
{"date", "%Y-%m-%d"},
{"time", "%H:%M:%S"},
{"year", "%Y"},
{"month", "%m"},
{"day", "%d"},
{"hour", "%H"},
{"minute", "%M"},
};

if (!formatMap.ContainsKey(condition.Part))
{
return $"{column} {condition.Operator} {value}";
}

var sql = $"strftime('{formatMap[condition.Part]}', {column}) {condition.Operator} cast({value} as text)";

if (condition.IsNot)
{
return $"NOT ({sql})";
}

return sql;
}

}
public static class SqliteCompilerExtensions
{
public static string ENGINE_CODE = "sqlite";
public static Query ForSqlite(this Query src, Func<Query, Query> fn)
{
return src.For(SqliteCompilerExtensions.ENGINE_CODE, fn);
}
}
}