Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jobily
Efcore.Pg
提交
61114c4f
E
Efcore.Pg
项目概览
jobily
/
Efcore.Pg
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
Efcore.Pg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
61114c4f
编写于
1月 25, 2021
作者:
S
Shay Rojansky
提交者:
GitHub
1月 25, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support PG extensions with schema (#1662)
Closes #1220
上级
eaf1c10d
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
99 addition
and
37 deletion
+99
-37
src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs
...FCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs
+5
-3
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
+12
-5
src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs
...ore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs
+7
-9
test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs
...ore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs
+16
-16
test/EFCore.PG.FunctionalTests/Scaffolding/NpgsqlDatabaseModelFactoryTest.cs
...tionalTests/Scaffolding/NpgsqlDatabaseModelFactoryTest.cs
+12
-4
test/EFCore.PG.Tests/Design/Internal/NpgsqlAnnotationCodeGeneratorTest.cs
...ests/Design/Internal/NpgsqlAnnotationCodeGeneratorTest.cs
+47
-0
未找到文件。
src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs
浏览文件 @
61114c4f
using
System
;
using
System.Collections.Generic
;
using
System.Diagnostics
;
using
System.Linq
;
using
JetBrains.Annotations
;
using
Microsoft.EntityFrameworkCore
;
...
...
@@ -86,8 +85,11 @@ protected override MethodCallCodeFragment GenerateFluentApi(IModel model, IAnnot
{
var
extension
=
new
PostgresExtension
(
model
,
annotation
.
Name
);
return
new
MethodCallCodeFragment
(
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
),
extension
.
Name
);
return
extension
.
Schema
==
"public"
||
extension
.
Schema
is
null
?
new
MethodCallCodeFragment
(
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
),
extension
.
Name
)
:
new
MethodCallCodeFragment
(
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
),
extension
.
Schema
,
extension
.
Name
);
}
if
(
annotation
.
Name
.
StartsWith
(
NpgsqlAnnotationNames
.
EnumPrefix
,
StringComparison
.
Ordinal
))
...
...
src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
浏览文件 @
61114c4f
...
...
@@ -924,18 +924,25 @@ protected override void Generate(EnsureSchemaOperation operation, IModel model,
[
NotNull
]
IModel
model
,
[
NotNull
]
MigrationCommandListBuilder
builder
)
{
var
schema
=
extension
.
Schema
??
model
.
GetDefaultSchema
();
// Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences
// and other database objects. However, it isn't aware of extensions, so we always ensure schema on enum creation.
if
(
schema
is
not
null
)
Generate
(
new
EnsureSchemaOperation
{
Name
=
schema
},
model
,
builder
);
builder
.
Append
(
"CREATE EXTENSION IF NOT EXISTS "
)
.
Append
(
DelimitIdentifier
(
extension
.
Name
));
if
(
extension
.
Schema
!=
null
)
if
(
extension
.
Schema
is
not
null
)
{
builder
.
Append
(
" SCHEMA "
)
.
Append
(
DelimitIdentifier
(
extension
.
Schema
));
}
if
(
extension
.
Version
!=
null
)
if
(
extension
.
Version
is
not
null
)
{
builder
.
Append
(
" VERSION "
)
...
...
@@ -1098,7 +1105,7 @@ protected override void Generate(EnsureSchemaOperation operation, IModel model,
// Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences
// and other database objects. However, it isn't aware of enums, so we always ensure schema on enum creation.
if
(
schema
!=
null
)
if
(
schema
is
not
null
)
Generate
(
new
EnsureSchemaOperation
{
Name
=
schema
},
model
,
builder
);
builder
...
...
@@ -1145,7 +1152,7 @@ protected override void Generate(EnsureSchemaOperation operation, IModel model,
.
Append
(
" ADD VALUE "
)
.
Append
(
_stringTypeMapping
.
GenerateSqlLiteral
(
addedLabel
));
if
(
beforeLabel
!=
null
)
if
(
beforeLabel
is
not
null
)
{
builder
.
Append
(
" BEFORE "
)
...
...
@@ -1197,7 +1204,7 @@ protected override void Generate(EnsureSchemaOperation operation, IModel model,
// Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences
// and other database objects. However, it isn't aware of ranges, so we always ensure schema on range creation.
if
(
schema
!=
null
)
if
(
schema
is
not
null
)
Generate
(
new
EnsureSchemaOperation
{
Name
=
schema
},
model
,
builder
);
builder
...
...
src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs
浏览文件 @
61114c4f
...
...
@@ -930,24 +930,22 @@ FROM pg_enum
/// </summary>
static
void
GetExtensions
(
NpgsqlConnection
connection
,
DatabaseModel
databaseModel
)
{
const
string
commandText
=
"SELECT name, default_version, installed_version FROM pg_available_extensions"
;
const
string
commandText
=
@"
SELECT ns.nspname, extname, extversion FROM pg_extension
JOIN pg_namespace ns ON ns.oid=extnamespace"
;
using
var
command
=
new
NpgsqlCommand
(
commandText
,
connection
);
using
var
reader
=
command
.
ExecuteReader
();
while
(
reader
.
Read
())
{
var
name
=
reader
.
GetString
(
reader
.
GetOrdinal
(
"name"
));
var
_
=
reader
.
GetValueOrDefault
<
string
>(
"default_version"
);
var
installedVersion
=
reader
.
GetValueOrDefault
<
string
>(
"installed_version"
);
if
(
installedVersion
==
null
)
continue
;
var
schema
=
reader
.
GetFieldValue
<
string
?>(
"nspname"
);
var
name
=
reader
.
GetString
(
reader
.
GetOrdinal
(
"extname"
));
var
version
=
reader
.
GetValueOrDefault
<
string
>(
"extversion"
);
if
(
name
==
"plpgsql"
)
// Implicitly installed in all PG databases
continue
;
// TODO: how/should we query the schema?
databaseModel
.
GetOrAddPostgresExtension
(
null
,
name
,
installedVersion
);
databaseModel
.
GetOrAddPostgresExtension
(
schema
,
name
,
version
);
}
}
...
...
test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs
浏览文件 @
61114c4f
...
...
@@ -2191,30 +2191,30 @@ public virtual async Task Ensure_postgres_extension()
{
var
citext
=
Assert
.
Single
(
model
.
GetPostgresExtensions
());
Assert
.
Equal
(
"citext"
,
citext
.
Name
);
Assert
.
Null
(
citext
.
Schema
);
Assert
.
Equal
(
"public"
,
citext
.
Schema
);
});
AssertSql
(
@"CREATE EXTENSION IF NOT EXISTS citext;"
);
}
public
virtual
Task
Ensure_postgres_extension_with_extension
()
[
Fact
]
public
virtual
async
Task
Ensure_postgres_extension_with_schema
()
{
// See https://github.com/npgsql/efcore.pg/issues/1220
return
Task
.
CompletedTask
;
await
Test
(
_
=>
{
},
builder
=>
builder
.
HasPostgresExtension
(
"some_schema"
,
"citext"
),
model
=>
{
var
citext
=
Assert
.
Single
(
model
.
GetPostgresExtensions
());
Assert
.
Equal
(
"citext"
,
citext
.
Name
);
Assert
.
Equal
(
"some_schema"
,
citext
.
Schema
);
});
// await Test(
// builder => { },
// builder => builder.HasPostgresExtension("some_schema", "citext"),
// model =>
// {
// var citext = Assert.Single(model.GetPostgresExtensions());
// Assert.Equal("citext", citext.Name);
// Assert.Equal("some_schema", citext.Schema);
// });
//
// AssertSql(
// @"CREATE EXTENSION IF NOT EXISTS citext;");
AssertSql
(
@"CREATE SCHEMA IF NOT EXISTS some_schema;"
,
//
@"CREATE EXTENSION IF NOT EXISTS citext SCHEMA some_schema;"
);
}
#
endregion
...
...
test/EFCore.PG.FunctionalTests/Scaffolding/NpgsqlDatabaseModelFactoryTest.cs
浏览文件 @
61114c4f
...
...
@@ -1799,15 +1799,23 @@ public void Dropped_columns()
public
void
Postgres_extensions
()
=>
Test
(
@"
CREATE EXTENSION hstore;
CREATE EXTENSION pgcrypto;"
,
CREATE EXTENSION pgcrypto
SCHEMA db2
;"
,
Enumerable
.
Empty
<
string
>(),
Enumerable
.
Empty
<
string
>(),
dbModel
=>
{
var
extensions
=
dbModel
.
GetPostgresExtensions
();
Assert
.
Equal
(
2
,
extensions
.
Count
);
Assert
.
Single
(
extensions
,
e
=>
e
.
Name
==
"hstore"
);
Assert
.
Single
(
extensions
,
e
=>
e
.
Name
==
"pgcrypto"
);
Assert
.
Collection
(
extensions
.
OrderBy
(
e
=>
e
.
Name
),
e
=>
{
Assert
.
Equal
(
"hstore"
,
e
.
Name
);
Assert
.
Equal
(
"public"
,
e
.
Schema
);
},
e
=>
{
Assert
.
Equal
(
"pgcrypto"
,
e
.
Name
);
Assert
.
Equal
(
"db2"
,
e
.
Schema
);
});
},
"DROP EXTENSION hstore; DROP EXTENSION pgcrypto"
);
...
...
test/EFCore.PG.Tests/Design/Internal/NpgsqlAnnotationCodeGeneratorTest.cs
浏览文件 @
61114c4f
...
...
@@ -147,6 +147,53 @@ public void GenerateFluentApi_IProperty_works_with_HiLo()
schema
=>
Assert
.
Equal
(
"HiLoIndexSchema"
,
schema
));
}
[
ConditionalFact
]
public
void
Extension
()
{
var
generator
=
CreateGenerator
();
var
modelBuilder
=
new
ModelBuilder
(
NpgsqlConventionSetBuilder
.
Build
());
modelBuilder
.
HasPostgresExtension
(
"postgis"
);
var
model
=
modelBuilder
.
Model
;
var
annotations
=
model
.
GetAnnotations
().
ToDictionary
(
a
=>
a
.
Name
,
a
=>
a
);
var
result
=
generator
.
GenerateFluentApiCalls
(
model
,
annotations
)
.
Single
(
c
=>
c
.
Method
==
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
));
Assert
.
Collection
(
result
.
Arguments
,
name
=>
Assert
.
Equal
(
"postgis"
,
name
));
}
[
ConditionalFact
]
public
void
Extension_with_schema
()
{
var
generator
=
CreateGenerator
();
var
modelBuilder
=
new
ModelBuilder
(
NpgsqlConventionSetBuilder
.
Build
());
modelBuilder
.
HasPostgresExtension
(
"some_schema"
,
"postgis"
);
var
model
=
modelBuilder
.
Model
;
var
annotations
=
model
.
GetAnnotations
().
ToDictionary
(
a
=>
a
.
Name
,
a
=>
a
);
var
result
=
generator
.
GenerateFluentApiCalls
(
model
,
annotations
)
.
Single
(
c
=>
c
.
Method
==
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
));
Assert
.
Collection
(
result
.
Arguments
,
schema
=>
Assert
.
Equal
(
"some_schema"
,
schema
),
name
=>
Assert
.
Equal
(
"postgis"
,
name
));
}
[
ConditionalFact
]
public
void
Extension_with_null_schema
()
{
var
generator
=
CreateGenerator
();
var
modelBuilder
=
new
ModelBuilder
(
NpgsqlConventionSetBuilder
.
Build
());
modelBuilder
.
HasPostgresExtension
(
null
,
"postgis"
);
var
model
=
modelBuilder
.
Model
;
var
annotations
=
model
.
GetAnnotations
().
ToDictionary
(
a
=>
a
.
Name
,
a
=>
a
);
var
result
=
generator
.
GenerateFluentApiCalls
(
model
,
annotations
)
.
Single
(
c
=>
c
.
Method
==
nameof
(
NpgsqlModelBuilderExtensions
.
HasPostgresExtension
));
Assert
.
Collection
(
result
.
Arguments
,
name
=>
Assert
.
Equal
(
"postgis"
,
name
));
}
NpgsqlAnnotationCodeGenerator
CreateGenerator
()
=>
new
(
new
AnnotationCodeGeneratorDependencies
(
new
NpgsqlTypeMappingSource
(
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录