-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sync to 5.0.0-alpha.1.20073.3 #1234
Conversation
d37adcf
to
f95a1ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partly reviewed the PR and will continue tomorrow.
@@ -66,16 +98,39 @@ public static class NpgsqlDbContextOptionsExtensions | |||
var extension = (NpgsqlOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnection(connection); | |||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); | |||
|
|||
ConfigureWarnings(optionsBuilder); | |||
|
|||
npgsqlOptionsAction?.Invoke(new NpgsqlDbContextOptionsBuilder(optionsBuilder)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lines are repeated multiple times, so it's worth to make a private method for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. But since this class is basically a copy-paste from EF Core, I prefer to just leave things like they are upstream... And there's not huge value here in the private method.
src/EFCore.PG/Extensions/NpgsqlDbContextOptionsBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
.Append(" INCLUDE (") | ||
.Append(ColumnList(includeColumns)) | ||
.Append(")"); | ||
if (operation[NpgsqlAnnotationNames.IndexInclude] is string[] includeColumns && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested condition can be safely merged with the outer since there are no returns on else
blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Note that I wasn't totally sure here about something - would be good to have your opinion (also @bricelam's).
In most cases, if something isn't supported, I prefer throwing an exception to make it clear to the user. In the case of index-included properties, for old versions which don't support this, for now I've decided to simply ignore - creating the index without the included properties. This is because included properties are an optional feature which only improves perf, and this makes the same model usable on any version of PG: with newer versions we get the speedup, with older versions we don't.
Does this make sense? Or is it better to throw on older versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing or ignoring both seem fine to me. Did you consider logging a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I keep forgetting those :) Ignoring and logging does sound like the way to go.
{ | ||
[DebuggerStepThrough] | ||
public static T GetValueOrDefault<T>([NotNull] this DbDataReader reader, [NotNull] string name) | ||
[return: MaybeNull] | ||
internal static T GetValueOrDefault<T>(this DbDataReader reader, string name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case a reader is not NpgsqlDataReader
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our code I think it's always NpgsqlDataReader - but it doesn't really make a difference.. Any reason to change it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since NpgsqlDataReader
is a final class the JIT could inline calls if they meet requirements. Another reason is that it's an internal extension method which is for Npgsql only, no need in an additional abstraction.
@@ -215,15 +207,16 @@ public override DatabaseModel Create(DbConnection dbConnection, DatabaseModelFac | |||
{ | |||
while (reader.Read()) | |||
{ | |||
var table = new DatabaseTable | |||
var schema = reader.GetValueOrDefault<string>("nspname"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you're using extensions here. I have fixed all methods on the command to return an NpgsqlDataReader
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Any reason to do any change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
See dotnet/efcore#16200 Follows 690ebc4540334c1d0938660a5960a25d4338acd4 in EF Core
No problem and thanks! Have addressed the comments you've already made. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope reviewed it carefully...
src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs
Outdated
Show resolved
Hide resolved
@@ -1083,6 +1033,7 @@ static SequenceInfo ReadSequenceInfo(DbDataRecord record, Version postgresVersio | |||
|
|||
class SequenceInfo | |||
{ | |||
public SequenceInfo(string storeType) => StoreType = storeType; | |||
public string StoreType { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove setter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just leaving it since everything else has a setter... It's just a temporarily values holder...
// { | ||
// DiffSnapshot(new BloggingContextModelSnapshot22(), context); | ||
// } | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was this way before too - I don't remember really. One day someone will look at it :)
AssertSql( | ||
@"ALTER TABLE ""People"" ALTER COLUMN ""FirstName"" TYPE text; | ||
ALTER TABLE ""People"" ALTER COLUMN ""FirstName"" SET NOT NULL; | ||
ALTER TABLE ""People"" ALTER COLUMN ""FirstName"" DROP DEFAULT;"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this style of assertion used in some places, but in others you put different commands in multiple strings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm mistaken, when you see multiple strings with a comment separating them, this means the migrations generator is generating multiple ADO commands. In other cases (like here), multiple statements are batched in the same command. In general it doesn't make much of a difference (we don't care about network roundtrips in migrations), but it could be an issue where we need to suppress transactions, since that holds for the entire command.
AssertSql( | ||
@"ALTER TABLE ""People"" DROP COLUMN ""Sum"";", | ||
// | ||
@"ALTER TABLE ""People"" ADD ""Sum"" integer GENERATED ALWAYS AS (""X"" + ""Y"") STORED;"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, there are two strings.
|
||
#region Helpers | ||
protected override void ClearLog() | ||
=> Fixture.TestSqlLoggerFactory.Clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does EF implement this method as no op?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because TestSqlLoggerFactory is a relational-only thing (SQL), but the test base class isn't relational - it is used also for non-relational databases. So you can think about ClearLog as a general, "clear all logs" that isn't SQL specific, which providers must then override to clear the log in their particular way (for relational databases that means clearing SQL).
For test base classes which are relational only this can and should be implemented at the base class.
protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) | ||
{ | ||
base.OnModelCreating(modelBuilder, context); | ||
|
||
modelBuilder.HasPostgresExtension("postgis"); | ||
} | ||
|
||
//protected override bool CanExecuteQueryString => true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we haven't implemented this yet, see #1232
{ | ||
public static NpgsqlDbContextOptionsBuilder ApplyConfiguration(this NpgsqlDbContextOptionsBuilder optionsBuilder) | ||
{ | ||
//optionsBuilder.ExecutionStrategy(d => new TestNpgsqlRetryingExecutionStrategy(d)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this introduces a lot of test breakage which I didn't want to deal with at this point. We should do this at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #1244 to track this.
test/EFCore.PG.FunctionalTests/TestUtilities/NpgsqlDbContextOptionsBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
.Generate(operation, modelBuilder.Model); | ||
|
||
Sql = string.Join( | ||
"GO" + EOL + EOL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is see an SQL Server directive!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a "delimiter" introduced in the tests to indicate a batch boundary (I've added a comment) - yes it's "inspired" by SQL Server :) Don't forget that these are just unit tests on the produced migrations DDL - nothing is executed on the database. Also note that this base class is copied as-is from EF Core, since there's no nuget package for the non-functional tests.
…ontext Closes npgsql#1174 Following dotnet/efcore#8427
Redo migration tests to actually execute DDL against the database. Follows #19039
Thanks for the review @YohDeadfall! Have answered all the comments above, if there's something you want more info on let me know. |
No description provided.