2020-12-20 08:36:11 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic ;
2017-09-20 20:06:46 +02:00
using NPoco ;
using NUnit.Framework ;
2021-02-10 14:45:44 +01:00
using Umbraco.Cms.Tests.Common.TestHelpers ;
2017-09-20 20:06:46 +02:00
using Umbraco.Core.Persistence ;
2017-12-28 09:06:33 +01:00
using Umbraco.Core.Persistence.Dtos ;
2020-12-20 08:36:11 +01:00
using Umbraco.Core.Persistence.Querying ;
2020-10-22 14:45:02 +02:00
using Umbraco.Tests.TestHelpers ;
2021-02-09 10:22:42 +01:00
using static Umbraco . Cms . Core . Persistence . SqlExtensionsStatics ;
2017-09-20 20:06:46 +02:00
2020-10-22 15:17:16 +02:00
namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Persistence.NPocoTests
2017-09-20 20:06:46 +02:00
{
[TestFixture]
2020-10-22 15:17:16 +02:00
public class NPocoSqlExtensionsTests : BaseUsingSqlSyntax
2017-09-20 20:06:46 +02:00
{
2018-12-04 08:23:18 +01:00
[Test]
public void WhereTest ( )
{
2020-12-20 08:36:11 +01:00
Sql < ISqlContext > sql = new Sql < ISqlContext > ( SqlContext )
2018-12-04 08:23:18 +01:00
. Select ( "*" )
. From < PropertyDataDto > ( )
. Where < PropertyDataDto > ( x = > x . LanguageId = = null ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] is null))" , sql . SQL , sql . SQL ) ;
sql = new Sql < ISqlContext > ( SqlContext )
. Select ( "*" )
. From < PropertyDataDto > ( )
. Where < PropertyDataDto > ( x = > x . LanguageId = = 123 ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))" , sql . SQL , sql . SQL ) ;
var id = 123 ;
sql = new Sql < ISqlContext > ( SqlContext )
. Select ( "*" )
. From < PropertyDataDto > ( )
. Where < PropertyDataDto > ( x = > x . LanguageId = = id ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))" , sql . SQL , sql . SQL ) ;
int? nid = 123 ;
sql = new Sql < ISqlContext > ( SqlContext )
. Select ( "*" )
. From < PropertyDataDto > ( )
. Where < PropertyDataDto > ( x = > x . LanguageId = = nid ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE (([umbracoPropertyData].[languageId] = @0))" , sql . SQL , sql . SQL ) ;
// but the above comparison fails if @0 is null
// what we want is something similar to:
sql = new Sql < ISqlContext > ( SqlContext )
. Select ( "*" )
. From < PropertyDataDto > ( )
. Where < PropertyDataDto > ( x = > ( nid = = null & & x . LanguageId = = null ) | | ( nid ! = null & & x . LanguageId = = nid ) ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE ((((@0 is null) AND ([umbracoPropertyData].[languageId] is null)) OR ((@1 is not null) AND ([umbracoPropertyData].[languageId] = @2))))" , sql . SQL , sql . SQL ) ;
2018-12-05 12:18:07 +01:00
// new SqlNullableEquals method does it automatically
2018-12-04 08:23:18 +01:00
// 'course it would be nicer if '==' could do it
2018-12-05 12:18:07 +01:00
// see note in ExpressionVisitorBase for SqlNullableEquals
2018-12-04 08:23:18 +01:00
2020-12-20 08:36:11 +01:00
// sql = new Sql<ISqlContext>(SqlContext)
2018-12-04 08:23:18 +01:00
// .Select("*")
// .From<PropertyDataDto>()
2018-12-05 12:18:07 +01:00
// .Where<PropertyDataDto>(x => x.LanguageId.SqlNullableEquals(nid));
2020-12-20 08:36:11 +01:00
// Assert.AreEqual("SELECT *\nFROM [umbracoPropertyData]\nWHERE ((((@0 is null) AND ([umbracoPropertyData].[languageId] is null)) OR ((@0 is not null) AND ([umbracoPropertyData].[languageId] = @0))))", sql.SQL, sql.SQL);
2018-12-04 08:23:18 +01:00
// but, the expression above fails with SQL CE, 'specified argument for the function is not valid' in 'isnull' function
// so... compare with fallback values
sql = new Sql < ISqlContext > ( SqlContext )
. Select ( "*" )
. From < PropertyDataDto > ( )
2018-12-05 12:18:07 +01:00
. Where < PropertyDataDto > ( x = > x . LanguageId . SqlNullableEquals ( nid , - 1 ) ) ;
2018-12-04 08:23:18 +01:00
Assert . AreEqual ( "SELECT *\nFROM [umbracoPropertyData]\nWHERE ((COALESCE([umbracoPropertyData].[languageId],@0) = COALESCE(@1,@0)))" , sql . SQL , sql . SQL ) ;
}
[Test]
2018-12-05 12:18:07 +01:00
public void SqlNullableEqualsTest ( )
2018-12-04 08:23:18 +01:00
{
int? a , b ;
a = b = null ;
2018-12-05 12:18:07 +01:00
Assert . IsTrue ( a . SqlNullableEquals ( b , - 1 ) ) ;
2018-12-04 08:23:18 +01:00
b = 2 ;
2018-12-05 12:18:07 +01:00
Assert . IsFalse ( a . SqlNullableEquals ( b , - 1 ) ) ;
2018-12-04 08:23:18 +01:00
a = 2 ;
2018-12-05 12:18:07 +01:00
Assert . IsTrue ( a . SqlNullableEquals ( b , - 1 ) ) ;
2018-12-04 08:23:18 +01:00
b = null ;
2018-12-05 12:18:07 +01:00
Assert . IsFalse ( a . SqlNullableEquals ( b , - 1 ) ) ;
2018-12-04 08:23:18 +01:00
}
2017-09-20 20:06:46 +02:00
[Test]
public void WhereInValueFieldTest ( )
{
2020-12-20 08:36:11 +01:00
Sql < ISqlContext > sql = new Sql < ISqlContext > ( SqlContext )
2017-09-20 20:06:46 +02:00
. Select ( "*" )
. From < NodeDto > ( )
. WhereIn < NodeDto > ( x = > x . NodeId , new [ ] { 1 , 2 , 3 } ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoNode]\nWHERE ([umbracoNode].[id] IN (@0,@1,@2))" , sql . SQL ) ;
}
[Test]
public void WhereInObjectFieldTest ( )
{
// this test used to fail because x => x.Text was evaluated as a lambda
// and returned "[umbracoNode].[text] = @0"... had to fix WhereIn.
2020-12-20 08:36:11 +01:00
Sql < ISqlContext > sql = new Sql < ISqlContext > ( SqlContext )
2017-09-20 20:06:46 +02:00
. Select ( "*" )
. From < NodeDto > ( )
. WhereIn < NodeDto > ( x = > x . Text , new [ ] { "a" , "b" , "c" } ) ;
Assert . AreEqual ( "SELECT *\nFROM [umbracoNode]\nWHERE ([umbracoNode].[text] IN (@0,@1,@2))" , sql . SQL ) ;
}
[Test]
2017-09-22 15:23:46 +02:00
public void SelectTests ( )
2017-09-20 20:06:46 +02:00
{
2017-09-22 15:23:46 +02:00
// select the whole DTO
2020-12-20 08:36:11 +01:00
Sql < ISqlContext > sql = Sql ( )
2017-09-22 15:23:46 +02:00
. Select < Dto1 > ( )
. From < Dto1 > ( ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value] FROM [dto1]" , sql . SQL . NoCrLf ( ) ) ;
// select only 1 field
sql = Sql ( )
. Select < Dto1 > ( x = > x . Id )
. From < Dto1 > ( ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id] FROM [dto1]" , sql . SQL . NoCrLf ( ) ) ;
// select 2 fields
sql = Sql ( )
. Select < Dto1 > ( x = > x . Id , x = > x . Name )
. From < Dto1 > ( ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name] FROM [dto1]" , sql . SQL . NoCrLf ( ) ) ;
// select the whole DTO and a referenced DTO
sql = Sql ( )
. Select < Dto1 > ( r = > r . Select ( x = > x . Dto2 ) )
. From < Dto1 > ( )
. InnerJoin < Dto2 > ( ) . On < Dto1 , Dto2 > ( left = > left . Id , right = > right . Dto1Id ) ;
2020-12-20 08:36:11 +01:00
Assert . AreEqual (
@ "SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
2017-09-22 15:23:46 +02:00
, [ dto2 ] . [ id ] AS [ Dto2__Id ] , [ dto2 ] . [ dto1id ] AS [ Dto2__Dto1Id ] , [ dto2 ] . [ name ] AS [ Dto2__Name ]
FROM [ dto1 ]
INNER JOIN [ dto2 ] ON [ dto1 ] . [ id ] = [ dto2 ] . [ dto1id ] ".NoCrLf(), sql.SQL.NoCrLf(), sql.SQL);
// select the whole DTO and nested referenced DTOs
sql = Sql ( )
. Select < Dto1 > ( r = > r . Select ( x = > x . Dto2 , r1 = > r1 . Select ( x = > x . Dto3 ) ) )
. From < Dto1 > ( )
. InnerJoin < Dto2 > ( ) . On < Dto1 , Dto2 > ( left = > left . Id , right = > right . Dto1Id )
. InnerJoin < Dto3 > ( ) . On < Dto2 , Dto3 > ( left = > left . Id , right = > right . Dto2Id ) ;
2020-12-20 08:36:11 +01:00
Assert . AreEqual (
@ "SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
2017-09-22 15:23:46 +02:00
, [ dto2 ] . [ id ] AS [ Dto2__Id ] , [ dto2 ] . [ dto1id ] AS [ Dto2__Dto1Id ] , [ dto2 ] . [ name ] AS [ Dto2__Name ]
, [ dto3 ] . [ id ] AS [ Dto2__Dto3__Id ] , [ dto3 ] . [ dto2id ] AS [ Dto2__Dto3__Dto2Id ] , [ dto3 ] . [ name ] AS [ Dto2__Dto3__Name ]
FROM [ dto1 ]
INNER JOIN [ dto2 ] ON [ dto1 ] . [ id ] = [ dto2 ] . [ dto1id ]
INNER JOIN [ dto3 ] ON [ dto2 ] . [ id ] = [ dto3 ] . [ dto2id ] ".NoCrLf(), sql.SQL.NoCrLf());
// select the whole DTO and referenced DTOs
sql = Sql ( )
. Select < Dto1 > ( r = > r . Select ( x = > x . Dto2s ) )
. From < Dto1 > ( )
. InnerJoin < Dto2 > ( ) . On < Dto1 , Dto2 > ( left = > left . Id , right = > right . Dto1Id ) ;
2020-12-20 08:36:11 +01:00
Assert . AreEqual (
@ "SELECT [dto1].[id] AS [Id], [dto1].[name] AS [Name], [dto1].[value] AS [Value]
2017-09-22 15:23:46 +02:00
, [ dto2 ] . [ id ] AS [ Dto2s__Id ] , [ dto2 ] . [ dto1id ] AS [ Dto2s__Dto1Id ] , [ dto2 ] . [ name ] AS [ Dto2s__Name ]
FROM [ dto1 ]
INNER JOIN [ dto2 ] ON [ dto1 ] . [ id ] = [ dto2 ] . [ dto1id ] ".NoCrLf(), sql.SQL.NoCrLf());
2017-09-20 20:06:46 +02:00
}
2017-11-21 14:19:16 +01:00
[Test]
public void SelectAliasTests ( )
{
// and select - not good
var sql = Sql ( )
. Select < Dto1 > ( x = > x . Id )
. Select < Dto2 > ( x = > x . Id ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id] SELECT [dto2].[id] AS [Id]" . NoCrLf ( ) , sql . SQL . NoCrLf ( ) ) ;
// and select - good
sql = Sql ( )
. Select < Dto1 > ( x = > x . Id )
. AndSelect < Dto2 > ( x = > x . Id ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id] , [dto2].[id] AS [Id]" . NoCrLf ( ) , sql . SQL . NoCrLf ( ) ) ;
// and select + alias
sql = Sql ( )
. Select < Dto1 > ( x = > x . Id )
. AndSelect < Dto2 > ( x = > Alias ( x . Id , "id2" ) ) ;
Assert . AreEqual ( "SELECT [dto1].[id] AS [Id] , [dto2].[id] AS [id2]" . NoCrLf ( ) , sql . SQL . NoCrLf ( ) ) ;
}
2018-05-18 17:20:18 +02:00
[Test]
public void UpdateTests ( )
{
2020-12-20 08:36:11 +01:00
Sql < ISqlContext > sql = Sql ( )
2018-05-18 17:20:18 +02:00
. Update < DataTypeDto > ( u = > u . Set ( x = > x . EditorAlias , "Umbraco.ColorPicker" ) )
. Where < DataTypeDto > ( x = > x . EditorAlias = = "Umbraco.ColorPickerAlias" ) ;
}
2017-09-22 15:23:46 +02:00
[TableName("dto1")]
[PrimaryKey("id", AutoIncrement = false)]
[ExplicitColumns]
public class Dto1
2017-09-20 20:06:46 +02:00
{
2017-09-22 15:23:46 +02:00
[Column("id")]
public int Id { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("name")]
public string Name { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("value")]
public int Value { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Reference]
public Dto2 Dto2 { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Reference]
public List < Dto2 > Dto2s { get ; set ; }
}
2017-09-20 20:06:46 +02:00
2017-09-22 15:23:46 +02:00
[TableName("dto2")]
[PrimaryKey("id", AutoIncrement = false)]
[ExplicitColumns]
public class Dto2
{
[Column("id")]
public int Id { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("dto1id")]
public int Dto1Id { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("name")]
public string Name { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Reference]
public Dto3 Dto3 { get ; set ; }
2017-09-20 20:06:46 +02:00
}
2017-09-22 15:23:46 +02:00
[TableName("dto3")]
[PrimaryKey("id", AutoIncrement = false)]
[ExplicitColumns]
public class Dto3
2017-09-20 20:06:46 +02:00
{
2017-09-22 15:23:46 +02:00
[Column("id")]
public int Id { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("dto2id")]
public int Dto2Id { get ; set ; }
2020-12-20 08:36:11 +01:00
2017-09-22 15:23:46 +02:00
[Column("name")]
public string Name { get ; set ; }
2017-09-20 20:06:46 +02:00
}
}
}