Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 3587e92

Browse files
author
TroyDycavinu-AI
committed
Merge branch 'master' of github.com:ServiceStack/ServiceStack.OrmLite
2 parents 580266f + 6cb4f73 commit 3587e92

27 files changed

+490
-74
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" },
298298

299299
```csharp
300300
db.UpdateOnly(new Person { FirstName = "JJ" },
301-
onlyFields: q => 1.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi"));
301+
onlyFields: q => q.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi"));
302302
```
303303
**UPDATE "Person" SET "FirstName" = 'JJ' WHERE ("LastName" = 'Hendrix')**
304304

@@ -498,12 +498,12 @@ The above query implicitly joins together the `Customer` and `CustomerAddress` P
498498

499499
```csharp
500500
class Customer {
501-
public Id { get; set; }
501+
public int Id { get; set; }
502502
...
503503
}
504504
class CustomerAddress {
505-
public Id { get; set; }
506-
public CustomerId { get; set; } // Reference based on Property name convention
505+
public int Id { get; set; }
506+
public int CustomerId { get; set; } // Reference based on Property name convention
507507
}
508508
```
509509

@@ -512,14 +512,14 @@ References based on matching alias names is also supported, e.g:
512512
```csharp
513513
[Alias("LegacyCustomer")]
514514
class Customer {
515-
public Id { get; set; }
515+
public int Id { get; set; }
516516
...
517517
}
518518
class CustomerAddress {
519-
public Id { get; set; }
519+
public int Id { get; set; }
520520

521521
[Alias("LegacyCustomerId")] // Matches `LegacyCustomer` Alias
522-
public RenamedCustomerId { get; set; } // Reference based on Alias Convention
522+
public int RenamedCustomerId { get; set; } // Reference based on Alias Convention
523523
}
524524
```
525525

lib/ServiceStack.Text.dll

0 Bytes
Binary file not shown.

lib/ServiceStack.Text.pdb

0 Bytes
Binary file not shown.

src/ServiceStack.OrmLite.MySql.Tests/UseCase/SimpleUseCase.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void TestFixtureSetUp()
1616
OrmLiteConfig.DialectProvider = MySqlDialectProvider.Instance;
1717
}
1818

19-
public class User
19+
public class UserWithIndex
2020
{
2121
public long Id { get; set; }
2222

@@ -31,13 +31,13 @@ public void Simple_CRUD_example()
3131
{
3232
using (IDbConnection db = ConfigurationManager.ConnectionStrings["testDb"].ConnectionString.OpenDbConnection())
3333
{
34-
db.CreateTable<User>(true);
34+
db.CreateTable<UserWithIndex>(true);
3535

36-
db.Insert(new User { Id = 1, Name = "A", CreatedDate = DateTime.Now });
37-
db.Insert(new User { Id = 2, Name = "B", CreatedDate = DateTime.Now });
38-
db.Insert(new User { Id = 3, Name = "B", CreatedDate = DateTime.Now });
36+
db.Insert(new UserWithIndex { Id = 1, Name = "A", CreatedDate = DateTime.Now });
37+
db.Insert(new UserWithIndex { Id = 2, Name = "B", CreatedDate = DateTime.Now });
38+
db.Insert(new UserWithIndex { Id = 3, Name = "B", CreatedDate = DateTime.Now });
3939

40-
var rowsB = db.SelectFmt<User>("Name = {0}", "B");
40+
var rowsB = db.SelectFmt<UserWithIndex>("Name = {0}", "B");
4141

4242
Assert.That(rowsB, Has.Count.EqualTo(2));
4343

@@ -46,10 +46,10 @@ public void Simple_CRUD_example()
4646

4747
rowsB.ForEach(x => db.Delete(x));
4848

49-
rowsB = db.SelectFmt<User>("Name = {0}", "B");
49+
rowsB = db.SelectFmt<UserWithIndex>("Name = {0}", "B");
5050
Assert.That(rowsB, Has.Count.EqualTo(0));
5151

52-
var rowsLeft = db.Select<User>();
52+
var rowsLeft = db.Select<UserWithIndex>();
5353
Assert.That(rowsLeft, Has.Count.EqualTo(1));
5454

5555
Assert.That(rowsLeft[0].Name, Is.EqualTo("A"));

src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteInsertTests.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
using System.Globalization;
33
using NUnit.Framework;
44
using ServiceStack.Common.Tests.Models;
5-
using ServiceStack.DataAnnotations;
6-
5+
using ServiceStack.DataAnnotations;
6+
using ServiceStack.Text;
7+
78
namespace ServiceStack.OrmLite.Tests
89
{
910
[TestFixture]
1011
public class OrmLiteInsertTests
1112
: OrmLiteTestBase
12-
{
13+
{
14+
public OrmLiteInsertTests() : base(Dialect.PostgreSql) { }
1315

1416
[Test]
1517
public void Can_insert_into_ModelWithFieldsOfDifferentTypes_table()
@@ -109,22 +111,47 @@ public void Can_retrieve_LastInsertId_from_inserted_table()
109111
db.CreateTable<ModelWithIdAndName1>(true);
110112

111113
var row1 = new ModelWithIdAndName1() { Name = "A", Id = 4 };
112-
var row2 = new ModelWithIdAndName1() { Name = "B", Id = 5 };
113-
114-
db.Insert(row1);
115-
var row1LastInsertId = db.LastInsertId();
116-
117-
db.Insert(row2);
118-
var row2LastInsertId = db.LastInsertId();
114+
var row2 = new ModelWithIdAndName1() { Name = "B", Id = 5 };
115+
116+
var row1LastInsertId = db.Insert(row1, selectIdentity: true);
117+
Assert.That(db.GetLastSql(), Is.StringEnding(") RETURNING id"));
118+
119+
var row2LastInsertId = db.Insert(row2, selectIdentity: true);
120+
Assert.That(db.GetLastSql(), Is.StringEnding(") RETURNING id"));
119121

120122
var insertedRow1 = db.SingleById<ModelWithIdAndName1>(row1LastInsertId);
121123
var insertedRow2 = db.SingleById<ModelWithIdAndName1>(row2LastInsertId);
122124

123125
Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name));
124126
Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name));
125127
}
126-
}
127-
128+
}
129+
130+
[Test]
131+
public void Can_retrieve_LastInsertId_from_inserted_table_with_LastVal()
132+
{
133+
PostgreSQL.PostgreSQLDialectProvider.Instance.UseReturningForLastInsertId = false;
134+
using (var db = OpenDbConnection())
135+
{
136+
db.DropAndCreateTable<ModelWithIdAndName>();
137+
138+
var row1 = ModelWithIdAndName.Create(5);
139+
var row2 = ModelWithIdAndName.Create(6);
140+
141+
var row1LastInsertId = db.Insert(row1, selectIdentity: true);
142+
Assert.That(db.GetLastSql(), Is.StringEnding("; SELECT LASTVAL()"));
143+
144+
var row2LastInsertId = db.Insert(row2, selectIdentity: true);
145+
Assert.That(db.GetLastSql(), Is.StringEnding("; SELECT LASTVAL()"));
146+
147+
var insertedRow1 = db.SingleById<ModelWithIdAndName>(row1LastInsertId);
148+
var insertedRow2 = db.SingleById<ModelWithIdAndName>(row2LastInsertId);
149+
150+
Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name));
151+
Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name));
152+
}
153+
PostgreSQL.PostgreSQLDialectProvider.Instance.UseReturningForLastInsertId = true;
154+
}
128155

129156
[Test]
130157
public void Can_insert_single_quote()

src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class PostgreSQLDialectProvider : OrmLiteDialectProviderBase<PostgreSQLDi
1212
public static PostgreSQLDialectProvider Instance = new PostgreSQLDialectProvider();
1313
const string textColumnDefinition = "text";
1414

15+
public bool UseReturningForLastInsertId { get; set; }
16+
1517
public PostgreSQLDialectProvider()
1618
{
1719
base.AutoIncrementDefinition = "";
@@ -32,6 +34,7 @@ public PostgreSQLDialectProvider()
3234
base.MaxStringColumnDefinition = "TEXT";
3335
base.InitColumnTypeMap();
3436
base.SelectIdentitySql = "SELECT LASTVAL()";
37+
this.UseReturningForLastInsertId = true;
3538
this.NamingStrategy = new PostgreSqlNamingStrategy();
3639
this.StringSerializer = new JsonStringSerializer();
3740
}
@@ -302,5 +305,24 @@ internal string ToArray<T>(T[] source)
302305
}
303306
return "ARRAY[" + values + "]";
304307
}
308+
309+
public override long InsertAndGetLastInsertId<T>(IDbCommand dbCmd)
310+
{
311+
if (SelectIdentitySql == null)
312+
throw new NotImplementedException("Returning last inserted identity is not implemented on this DB Provider.");
313+
314+
if (UseReturningForLastInsertId)
315+
{
316+
var modelDef = GetModel(typeof(T));
317+
var pkName = NamingStrategy.GetColumnName(modelDef.PrimaryKey.FieldName);
318+
dbCmd.CommandText += " RETURNING " + pkName;
319+
}
320+
else
321+
{
322+
dbCmd.CommandText += "; " + SelectIdentitySql;
323+
}
324+
325+
return dbCmd.ExecLongScalar();
326+
}
305327
}
306328
}

src/ServiceStack.OrmLite.SqlServerV45/ServiceStack.OrmLite.SqlServerV45.Signed.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<DebugType>full</DebugType>
1818
<Optimize>false</Optimize>
1919
<OutputPath>bin\Debug\</OutputPath>
20-
<DefineConstants>DEBUG;TRACE</DefineConstants>
20+
<DefineConstants>TRACE;DEBUG;NET45</DefineConstants>
2121
<ErrorReport>prompt</ErrorReport>
2222
<WarningLevel>4</WarningLevel>
2323
</PropertyGroup>

src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ private SqlExpression<T> InternalJoin<Source, Target>(string joinType,
8484
return InternalJoin(joinType, joinExpr, sourceDef, targetDef);
8585
}
8686

87-
private string InternalCreateSqlFromExpression(Expression joinExpr)
87+
private string InternalCreateSqlFromExpression(Expression joinExpr, bool isCrossJoin)
8888
{
89-
return "ON {0}".Fmt(Visit(joinExpr).ToString());
89+
return "{0} {1}".Fmt((isCrossJoin ? "WHERE" : "ON"), Visit(joinExpr).ToString());
9090
}
9191

92-
private string InternalCreateSqlFromDefinitions(ModelDefinition sourceDef, ModelDefinition targetDef, bool allowMissingOnClause)
92+
private string InternalCreateSqlFromDefinitions(ModelDefinition sourceDef, ModelDefinition targetDef, bool isCrossJoin)
9393
{
9494
var parentDef = sourceDef;
9595
var childDef = targetDef;
@@ -104,13 +104,14 @@ private string InternalCreateSqlFromDefinitions(ModelDefinition sourceDef, Model
104104

105105
if (refField == null)
106106
{
107-
if(!allowMissingOnClause)
107+
if(!isCrossJoin)
108108
throw new ArgumentException("Could not infer relationship between {0} and {1}".Fmt(sourceDef.ModelName, targetDef.ModelName));
109109

110110
return string.Empty;
111111
}
112112

113-
return "ON\n({0}.{1} = {2}.{3})".Fmt(
113+
return "{0}\n({1}.{2} = {3}.{4})".Fmt(
114+
isCrossJoin ? "WHERE" : "ON",
114115
DialectProvider.GetQuotedTableName(parentDef),
115116
SqlColumn(parentDef.PrimaryKey.FieldName),
116117
DialectProvider.GetQuotedTableName(childDef),
@@ -126,9 +127,10 @@ private SqlExpression<T> InternalJoin(string joinType,
126127
useFieldName = true;
127128
sep = " ";
128129

130+
var isCrossJoin = "CROSS JOIN".Equals(joinType);
129131
var sqlExpr = joinExpr != null
130-
? InternalCreateSqlFromExpression(joinExpr)
131-
: InternalCreateSqlFromDefinitions(sourceDef, targetDef, "CROSS JOIN".Equals(joinType));
132+
? InternalCreateSqlFromExpression(joinExpr, isCrossJoin)
133+
: InternalCreateSqlFromDefinitions(sourceDef, targetDef, isCrossJoin);
132134

133135
var joinDef = tableDefs.Contains(targetDef) && !tableDefs.Contains(sourceDef)
134136
? sourceDef
@@ -181,7 +183,7 @@ public string SelectInto<TModel>()
181183
tableFieldDef.GetQuotedName(DialectProvider));
182184

183185
if (tableFieldDef.Alias != null)
184-
sbSelect.Append(" AS ").Append(DialectProvider.NamingStrategy.GetColumnName(fieldDef.Name));
186+
sbSelect.Append(" AS ").Append(SqlColumn(fieldDef.Name));
185187

186188
break;
187189
}
@@ -208,7 +210,7 @@ public string SelectInto<TModel>()
208210

209211
sbSelect.AppendFormat("{0} as {1}",
210212
DialectProvider.GetQuotedColumnName(tableDef, matchingField),
211-
fieldDef.Name);
213+
SqlColumn(fieldDef.Name));
212214

213215
break;
214216
}
@@ -217,7 +219,7 @@ public string SelectInto<TModel>()
217219
}
218220

219221
var columns = sbSelect.Length > 0 ? sbSelect.ToString() : "*";
220-
SelectExpression = "SELECT " + columns;
222+
SelectExpression = "SELECT " + (selectDistinct ? "DISTINCT " : "") + columns;
221223

222224
return ToSelectStatement();
223225
}

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public abstract partial class SqlExpression<T> : ISqlExpression
2525

2626
private string sep = string.Empty;
2727
protected bool useFieldName = false;
28+
protected bool selectDistinct = false;
2829
private ModelDefinition modelDef;
2930
public bool PrefixFieldWithTableName { get; set; }
3031
public bool WhereStatementWithoutWhereString { get; set; }
@@ -54,6 +55,7 @@ protected virtual SqlExpression<T> CopyTo(SqlExpression<T> to)
5455
to.underlyingExpression = underlyingExpression;
5556
to.orderByProperties = orderByProperties;
5657
to.selectExpression = selectExpression;
58+
to.selectDistinct = selectDistinct;
5759
to.fromExpression = fromExpression;
5860
to.whereExpression = whereExpression;
5961
to.groupBy = groupBy;
@@ -1257,8 +1259,10 @@ protected object GetQuotedFalseValue()
12571259

12581260
private void BuildSelectExpression(string fields, bool distinct)
12591261
{
1262+
selectDistinct = distinct;
1263+
12601264
selectExpression = string.Format("SELECT {0}{1}",
1261-
(distinct ? "DISTINCT " : ""),
1265+
(selectDistinct ? "DISTINCT " : ""),
12621266
(string.IsNullOrEmpty(fields) ?
12631267
DialectProvider.GetColumnNames(modelDef) :
12641268
fields));

src/ServiceStack.OrmLite/FieldDefinition.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,18 @@ public bool ShouldSkipDelete()
110110
{
111111
return IsComputed;
112112
}
113+
114+
public bool IsSelfRefField(FieldDefinition fieldDef)
115+
{
116+
return (fieldDef.Alias != null && IsSelfRefField(fieldDef.Alias))
117+
|| IsSelfRefField(fieldDef.Name);
118+
}
119+
120+
public bool IsSelfRefField(string name)
121+
{
122+
return (Alias != null && Alias + "Id" == name)
123+
|| Name + "Id" == name;
124+
}
113125
}
114126

115127
public class ForeignKeyConstraint

0 commit comments

Comments
 (0)