├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.sources.list ├── .travis.yml ├── Directory.Build.props ├── EFCore.FirebirdSQL.sln ├── EFCore.FirebirdSql.FunctionalTests ├── Directory.Build.props ├── EFCore.FirebirdSql.FunctionalTests.csproj ├── Util │ └── ExtensionSql.cs └── xunit.runner.json ├── EFCore.FirebirdSql ├── Design │ └── Internal │ │ ├── FbAnnotationCodeGenerator.cs │ │ └── FbDesignTimeServices.cs ├── Diagnostics │ └── FbEventId.cs ├── EFCore.FirebirdSql.csproj ├── EntityFramework.FirebirdSQL.snk ├── Extensions │ ├── FbDatabaseFacadeExtensions.cs │ ├── FbDbContextOptionsExtensions.cs │ ├── FbMetadataExtensions.cs │ ├── FbModelBuilderExtensions.cs │ ├── FbPropertyBuilderExtensions.cs │ ├── FbQueryableExtensions.cs │ ├── FbServiceCollectionExtensions.cs │ ├── FbSharedType.cs │ ├── FbStringExtension.cs │ └── StringBuilderExtensions.cs ├── Infrastructure │ ├── FbDbContextOptionsBuilder.cs │ └── Internal │ │ ├── FbOptionsExtension.cs │ │ └── IFbOptions.cs ├── Internal │ ├── FbLoggerExtensions.cs │ └── FbOptions.cs ├── Metadata │ ├── Conventions │ │ ├── FbConventionSetBuilder.cs │ │ └── Internal │ │ │ └── FbValueGenerationStrategyConvention.cs │ ├── FbModelAnnotations.cs │ ├── FbPropertyAnnotations.cs │ ├── FbValueGenerationStrategy.cs │ ├── IFbModelAnnotations.cs │ ├── IFbPropertyAnnotations.cs │ └── Internal │ │ ├── FbAnnotationNames.cs │ │ ├── FbInternalMetadataBuilderExtensions.cs │ │ ├── FbModelBuilderAnnotations.cs │ │ └── FbPropertyBuilderAnnotations.cs ├── Migrations │ ├── FbMigrationSqlGeneratorBehavior.cs │ ├── FbMigrationsSqlGenerator.cs │ ├── IFbMigrationSqlGeneratorBehavior.cs │ ├── Internal │ │ ├── FbHistoryRepository.cs │ │ └── FbMigrationsAnnotationProvider.cs │ └── Operations │ │ ├── FbCreateDatabaseOperation.cs │ │ └── FbDropDatabaseOperation.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── FbStrings.Designer.cs │ ├── FbStrings.Designer.tt │ ├── FbStrings.resx │ ├── FirebirdSql.EntityFrameworkCore.Firebird.snk │ ├── InternalsVisibleTo.cs │ ├── PublishProfiles │ │ └── FolderProfile.pubxml │ ├── Resources.cs │ └── Resources.tt ├── Query │ ├── ExpressionTranslators │ │ └── Internal │ │ │ ├── FbContainsOptimizedTranslator.cs │ │ │ ├── FbConvertTranslator.cs │ │ │ ├── FbDateAddTranslator.cs │ │ │ ├── FbDateTimeMemberTranslator.cs │ │ │ ├── FbEndsWithOptimizedTranslator.cs │ │ │ ├── FbMathTranslator.cs │ │ │ ├── FbNewGuidTranslator.cs │ │ │ ├── FbObjectToStringTranslator.cs │ │ │ ├── FbStartsWithOptimizedTranslator.cs │ │ │ ├── FbStringIsNullOrWhiteSpaceTranslator.cs │ │ │ ├── FbStringLengthTranslator.cs │ │ │ ├── FbStringReplaceTranslator.cs │ │ │ ├── FbStringSubstringTranslator.cs │ │ │ ├── FbStringToLowerTranslator.cs │ │ │ ├── FbStringToUpperTranslator.cs │ │ │ └── FbStringTrimTranslator.cs │ ├── ExpressionVisitors │ │ └── Internal │ │ │ ├── FbSqlTranslatingExpressionVisitor.cs │ │ │ └── FbSqlTranslatingExpressionVisitorFactory.cs │ ├── Expressions │ │ └── Internal │ │ │ ├── FbExtractExpression.cs │ │ │ └── FbStringExpression.cs │ ├── FbCompilationContextFactory.cs │ ├── MethodsTranslators │ │ ├── FbCompositeMemberTranslator.cs │ │ └── FbCompositeMethodCallTranslator.cs │ ├── Operators │ │ ├── WithLockExpressionNode.cs │ │ └── WithLockResultOperator.cs │ └── Sql │ │ └── Internal │ │ ├── FbQuerySqlGenerator.cs │ │ ├── FbQuerySqlGeneratorFactory.cs │ │ └── IFbExpressionVisitor.cs ├── Scaffolding │ ├── Internal │ │ ├── FbDataReaderExtension.cs │ │ ├── FbDatabaseModelFactory.cs │ │ └── FbScaffoldingCodeGenerator.cs │ └── Metadata │ │ ├── FbColumnModelAnnotations.cs │ │ ├── FbDatabaseModelAnnotationNames.cs │ │ ├── FbDatabaseModelExtensions.cs │ │ └── FbIndexModelAnnotations.cs ├── Storage │ └── Internal │ │ ├── FbDatabaseCreator.cs │ │ ├── FbRelationalCommand.cs │ │ ├── FbRelationalConnection.cs │ │ ├── FbRelationalTransaction.cs │ │ ├── FbSqlGeneratorHelper.cs │ │ ├── IFbRelationalConnection.cs │ │ ├── IFbSqlGeneratorHelper.cs │ │ └── Mapping │ │ ├── FbBoolTypeMapping.cs │ │ ├── FbByteArrayTypeMapping.cs │ │ ├── FbDateTimeTypeMapping.cs │ │ ├── FbGuidTypeMapping.cs │ │ ├── FbStringTypeMapping.cs │ │ ├── FbTypeMapping.cs │ │ └── FbTypeMappingSource.cs ├── Update │ └── Internal │ │ ├── FbBatchExecutor.cs │ │ ├── FbModificationCommandBatchFactory.cs │ │ ├── FbUpdateSqlGenerator.cs │ │ └── IFbUpdateSqlGenerator.cs ├── Utilities │ └── TranslatorMethods.cs └── ValueGeneration │ └── Internal │ ├── FbSequentialGuidValueGenerator.cs │ └── FbValueGeneratorSelector.cs ├── EFCore.FirerbirdSql.ScaffoldTest ├── EFCore.FirerbirdSql.ScaffoldTest.csproj ├── Program.cs └── scaffold.ps1 ├── ISSUE_TEMPLATE.md ├── LICENSE ├── NuGet.Config ├── README.md ├── appveyor.yml └── msbuild.binlog /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc 262 | *.FDB 263 | 264 | # EF scaffolding test result 265 | EFCore.FirerbirdSql.ScaffoldTest/Scaffolded/ -------------------------------------------------------------------------------- /.travis.sources.list: -------------------------------------------------------------------------------- 1 | # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to 2 | # newer versions of the distribution. 3 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial main restricted 4 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial main restricted 5 | 6 | ## Major bug fix updates produced after the final release of the 7 | ## distribution. 8 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates main restricted 9 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates main restricted 10 | 11 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu 12 | ## team. Also, please note that software in universe WILL NOT receive any 13 | ## review or updates from the Ubuntu security team. 14 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial universe 15 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial universe 16 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates universe 17 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates universe 18 | 19 | ## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu 20 | ## team, and may not be under a free licence. Please satisfy yourself as to 21 | ## your rights to use the software. Also, please note that software in 22 | ## multiverse WILL NOT receive any review or updates from the Ubuntu 23 | ## security team. 24 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial multiverse 25 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial multiverse 26 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates multiverse 27 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-updates multiverse 28 | 29 | ## N.B. software from this repository may not have been tested as 30 | ## extensively as that contained in the main release, although it includes 31 | ## newer versions of some applications which may provide useful features. 32 | ## Also, please note that software in backports WILL NOT receive any review 33 | ## or updates from the Ubuntu security team. 34 | deb http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse 35 | deb-src http://us-central1.gce.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse 36 | 37 | deb http://security.ubuntu.com/ubuntu xenial-security main restricted 38 | deb-src http://security.ubuntu.com/ubuntu xenial-security main restricted 39 | deb http://security.ubuntu.com/ubuntu xenial-security universe 40 | deb-src http://security.ubuntu.com/ubuntu xenial-security universe 41 | deb http://security.ubuntu.com/ubuntu xenial-security multiverse 42 | deb-src http://security.ubuntu.com/ubuntu xenial-security multiverse -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | mono: none 3 | dotnet: 2.0.0 4 | dist: trusty 5 | sudo: required 6 | 7 | services: 8 | - docker 9 | 10 | branches: 11 | only: 12 | - master 13 | - release 14 | - dev 15 | - /^.*-wip$/ 16 | - /^(.*\/)?ci-.*$/ 17 | 18 | before_install: 19 | - docker run -d --name firebird -p 3050:3050 almeida/firebird 20 | - docker run -v $(pwd):/dotnet/:rw -e 'CI=True' --name dotnet --link firebird:firebird -d microsoft/dotnet:2.0.0-sdk sh -c 'while true; do sleep 0.1; done' 21 | 22 | script: 23 | - docker exec -it dotnet sh -c 'cd /dotnet/EFCore.FirebirdSql && dotnet restore' 24 | 25 | 26 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7.1 7 | 8 | 9 | -------------------------------------------------------------------------------- /EFCore.FirebirdSQL.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.FirebirdSql", "EFCore.FirebirdSql\EFCore.FirebirdSql.csproj", "{C725AC99-64C8-4CBF-B01F-094D5837BC58}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.FirebirdSql.FunctionalTests", "EFCore.FirebirdSql.FunctionalTests\EFCore.FirebirdSql.FunctionalTests.csproj", "{61B6B2E6-80B0-4916-8EE4-91D059CB204F}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{684DA5D2-7DFC-4BD6-9870-4AC6D4341AEB}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | Directory.Build.props = Directory.Build.props 14 | EndProjectSection 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AEDA8CF6-1035-4556-B8D2-5822B04DA4D4}" 17 | EndProject 18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{8017995F-8C52-472B-99AA-38052452DAF7}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {C725AC99-64C8-4CBF-B01F-094D5837BC58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {C725AC99-64C8-4CBF-B01F-094D5837BC58}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {C725AC99-64C8-4CBF-B01F-094D5837BC58}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {C725AC99-64C8-4CBF-B01F-094D5837BC58}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {61B6B2E6-80B0-4916-8EE4-91D059CB204F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {61B6B2E6-80B0-4916-8EE4-91D059CB204F}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {61B6B2E6-80B0-4916-8EE4-91D059CB204F}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {61B6B2E6-80B0-4916-8EE4-91D059CB204F}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(NestedProjects) = preSolution 39 | {C725AC99-64C8-4CBF-B01F-094D5837BC58} = {AEDA8CF6-1035-4556-B8D2-5822B04DA4D4} 40 | {61B6B2E6-80B0-4916-8EE4-91D059CB204F} = {8017995F-8C52-472B-99AA-38052452DAF7} 41 | EndGlobalSection 42 | GlobalSection(ExtensibilityGlobals) = postSolution 43 | SolutionGuid = {CCB461D4-B163-4511-8434-CE0C357FDC74} 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql.FunctionalTests/Directory.Build.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | $(NoWarn);xUnit1004 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql.FunctionalTests/EFCore.FirebirdSql.FunctionalTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461 5 | false 6 | EFCore.FirebirdSql.FunctionalTests 7 | true 8 | ../EFCore.FirebirdSql/EntityFramework.FirebirdSQL.snk 9 | true 10 | false 11 | 12 | 13 | 14 | 7.2 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | all 43 | runtime; build; native; contentfiles; analyzers 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql.FunctionalTests/Util/ExtensionSql.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq; 18 | using System.Reflection; 19 | using Microsoft.EntityFrameworkCore.Query; 20 | using Microsoft.EntityFrameworkCore.Query.Internal; 21 | using Microsoft.EntityFrameworkCore.Storage; 22 | 23 | namespace EFCore.FirebirdSql.FunctionalTests 24 | { 25 | public static class ExtensionSql 26 | { 27 | private static readonly TypeInfo _queryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo(); 28 | 29 | private static readonly FieldInfo _queryCompiler 30 | = typeof(EntityQueryProvider) 31 | .GetTypeInfo() 32 | .DeclaredFields 33 | .Single(x => x.Name == "_queryCompiler"); 34 | 35 | private static readonly FieldInfo _queryModelGenerator 36 | = _queryCompilerTypeInfo 37 | .DeclaredFields 38 | .Single(x => x.Name == "_queryModelGenerator"); 39 | 40 | private static readonly FieldInfo _database = _queryCompilerTypeInfo 41 | .DeclaredFields 42 | .Single(x => x.Name == "_database"); 43 | 44 | private static readonly PropertyInfo _dependencies 45 | = typeof(Database) 46 | .GetTypeInfo() 47 | .DeclaredProperties 48 | .Single(x => x.Name == "Dependencies"); 49 | 50 | public static string ToSql(this IQueryable queryable) 51 | where T : class 52 | { 53 | var queryCompiler = _queryCompiler.GetValue(queryable.Provider) as IQueryCompiler; 54 | var queryModel = (_queryModelGenerator.GetValue(queryCompiler) as IQueryModelGenerator).ParseQuery(queryable.Expression); 55 | var queryCompilationContextFactory 56 | = ((DatabaseDependencies)_dependencies.GetValue(_database.GetValue(queryCompiler))) 57 | .QueryCompilationContextFactory; 58 | 59 | var queryCompilationContext = queryCompilationContextFactory.Create(false); 60 | var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); 61 | 62 | modelVisitor.CreateQueryExecutor(queryModel); 63 | 64 | return modelVisitor 65 | .Queries 66 | .FirstOrDefault() 67 | .ToString(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql.FunctionalTests/xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "appDomain": "denied" 3 | } 4 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Design/Internal/FbAnnotationCodeGenerator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Design; 18 | using Microsoft.EntityFrameworkCore.Infrastructure; 19 | using Microsoft.EntityFrameworkCore.Metadata; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Design.Internal 22 | { 23 | public class FbAnnotationCodeGenerator : AnnotationCodeGenerator 24 | { 25 | public FbAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) 26 | : base(dependencies) 27 | { } 28 | 29 | public override bool IsHandledByConvention(IModel model, IAnnotation annotation) => true; 30 | 31 | public override MethodCallCodeFragment GenerateFluentApi(IIndex index, IAnnotation annotation) => null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Design/Internal/FbDesignTimeServices.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 18 | using EntityFrameworkCore.FirebirdSql.Internal; 19 | using EntityFrameworkCore.FirebirdSql.Scaffolding.Internal; 20 | using EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping; 21 | using Microsoft.EntityFrameworkCore.Design; 22 | using Microsoft.EntityFrameworkCore.Scaffolding; 23 | using Microsoft.EntityFrameworkCore.Storage; 24 | using Microsoft.Extensions.DependencyInjection; 25 | 26 | namespace EntityFrameworkCore.FirebirdSql.Design.Internal 27 | { 28 | public class FbDesignTimeServices : IDesignTimeServices 29 | { 30 | public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollection) 31 | => serviceCollection 32 | .AddSingleton() 33 | .AddSingleton() 34 | .AddSingleton() 35 | .AddSingleton() 36 | .AddSingleton(); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/EFCore.FirebirdSql.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 3.6 6 | EntityFrameworkCore.FirebirdSql 7 | EntityFrameworkCore.FirebirdSql 8 | true 9 | true 10 | Copyright © 2017-2018 Rafael Almeida 11 | Ralms.net - ralms@ralms.net 12 | Rafael Almeida 13 | false 14 | git 15 | EntityFrameworkCore.FirebirdSQL; FirebirdSQL; EntityFrameworkCore; Entity Framework Core;entity-framework-core;EF;Data;O/RM 16 | EntityFrameworkCore.FirebirdSql is an ORM, created at the top of the Firebird ADO.NET (FirebirdSql.Data.FirebirdClient) Data Provider. It allows you to use Entity Framework Core 2.0/2.X as an extension, to access Firebird (2.x, 3.x, 4.x) 17 | true 18 | EntityFrameworkCore.FirebirdSql 19 | EntityFrameworkCore.FirebirdSQL 20 | https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL 21 | https://www.firebirdsql.org/file/about/firebird-logo-48.png 22 | https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSql/blob/master/LICENSE 23 | https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL 24 | 2.1.4 25 | 2.1.4.0 26 | 2.1.4.0 27 | 28 | EntityFramework.FirebirdSQL.snk 29 | 30 | 31 | 32 | true 33 | TRACE;DEBUG;EFCORE 34 | 7.2 35 | 1701;1702;IDE1006 36 | NU1605 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | True 52 | True 53 | FbStrings.Designer.tt 54 | 55 | 56 | True 57 | True 58 | Resources.tt 59 | 60 | 61 | 62 | 63 | 64 | EntityFrameworkCore.FirebirdSql.Internal 65 | 66 | 67 | 68 | 69 | 70 | TextTemplatingFileGenerator 71 | Resources.cs 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/EntityFramework.FirebirdSQL.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL/05de1b824cc917bc45b2b2c1a2c318761b9b8bee/EFCore.FirebirdSql/EntityFramework.FirebirdSQL.snk -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbDatabaseFacadeExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Reflection; 19 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 20 | using Microsoft.EntityFrameworkCore.Infrastructure; 21 | 22 | namespace Microsoft.EntityFrameworkCore 23 | { 24 | public static class FbDatabaseFacadeExtensions 25 | { 26 | public static bool IsFirebird(this DatabaseFacade database) 27 | => database.ProviderName 28 | .Equals(typeof(FbOptionsExtension) 29 | .GetTypeInfo().Assembly.GetName().Name, StringComparison.Ordinal); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbDbContextOptionsExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Data.Common; 19 | using EntityFrameworkCore.FirebirdSql.Infrastructure; 20 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 21 | using Microsoft.EntityFrameworkCore.Diagnostics; 22 | using Microsoft.EntityFrameworkCore.Infrastructure; 23 | 24 | namespace Microsoft.EntityFrameworkCore 25 | { 26 | public static class FbDbContextOptionsExtensions 27 | { 28 | public static DbContextOptionsBuilder UseFirebird( 29 | this DbContextOptionsBuilder optionsBuilder, 30 | string connectionString, 31 | Action FbOptionsAction = null) 32 | { 33 | var extension = (FbOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString); 34 | ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); 35 | FbOptionsAction?.Invoke(new FbDbContextOptionsBuilder(optionsBuilder)); 36 | ConfigureWarnings(optionsBuilder); 37 | return optionsBuilder; 38 | } 39 | 40 | public static DbContextOptionsBuilder UseFirebird( 41 | this DbContextOptionsBuilder optionsBuilder, 42 | DbConnection connection, 43 | Action fbOptionsAction = null) 44 | { 45 | var extension = (FbOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnection(connection); 46 | ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); 47 | fbOptionsAction?.Invoke(new FbDbContextOptionsBuilder(optionsBuilder)); 48 | ConfigureWarnings(optionsBuilder); 49 | return optionsBuilder; 50 | } 51 | 52 | public static DbContextOptionsBuilder UseFirebird( 53 | this DbContextOptionsBuilder optionsBuilder, 54 | string connectionString, 55 | Action fbOptionsAction = null) 56 | where TContext : DbContext 57 | => (DbContextOptionsBuilder)UseFirebird((DbContextOptionsBuilder)optionsBuilder, connectionString, fbOptionsAction); 58 | 59 | public static DbContextOptionsBuilder UseFirebird( 60 | this DbContextOptionsBuilder optionsBuilder, 61 | DbConnection connection, 62 | Action fbOptionsAction = null) 63 | where TContext : DbContext 64 | => (DbContextOptionsBuilder)UseFirebird((DbContextOptionsBuilder)optionsBuilder, connection, fbOptionsAction); 65 | 66 | private static FbOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder optionsBuilder) 67 | => optionsBuilder.Options.FindExtension() 68 | ?? new FbOptionsExtension(); 69 | 70 | private static void ConfigureWarnings(DbContextOptionsBuilder optionsBuilder) 71 | { 72 | var coreOptionsExtension 73 | = optionsBuilder.Options.FindExtension() 74 | ?? new CoreOptionsExtension(); 75 | 76 | coreOptionsExtension = coreOptionsExtension.WithWarningsConfiguration( 77 | coreOptionsExtension.WarningsConfiguration.TryWithExplicit( 78 | RelationalEventId.AmbientTransactionWarning, WarningBehavior.Throw)); 79 | 80 | ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(coreOptionsExtension); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbMetadataExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Metadata; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | 20 | namespace Microsoft.EntityFrameworkCore 21 | { 22 | public static class FbMetadataExtensions 23 | { 24 | public static FbPropertyAnnotations Firebird(this IProperty property) 25 | => new FbPropertyAnnotations(property); 26 | 27 | public static RelationalKeyAnnotations Firebird(this IKey key) 28 | => new RelationalKeyAnnotations(key); 29 | 30 | public static RelationalForeignKeyAnnotations Firebird(this IForeignKey foreignKey) 31 | => new RelationalForeignKeyAnnotations(foreignKey); 32 | 33 | public static RelationalIndexAnnotations Firebird(this IIndex index) 34 | => new RelationalIndexAnnotations(index); 35 | 36 | public static FbModelAnnotations Firebird(this IModel model) 37 | => new FbModelAnnotations(model); 38 | 39 | public static RelationalEntityTypeAnnotations Firebird(this IEntityType entityType) 40 | => new RelationalEntityTypeAnnotations(entityType); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbModelBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Metadata; 18 | 19 | namespace Microsoft.EntityFrameworkCore 20 | { 21 | public static class FbModelBuilderExtensions 22 | { 23 | public static ModelBuilder ForFbUseIdentityColumns(this ModelBuilder modelBuilder) 24 | { 25 | var property = modelBuilder.Model; 26 | property.Firebird().ValueGenerationStrategy = FbValueGenerationStrategy.IdentityColumn; 27 | return modelBuilder; 28 | } 29 | 30 | public static ModelBuilder ForFbUseTriggerColumns(this ModelBuilder modelBuilder) 31 | { 32 | var property = modelBuilder.Model; 33 | property.Firebird().ValueGenerationStrategy = FbValueGenerationStrategy.SequenceTrigger; 34 | return modelBuilder; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbPropertyBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | 18 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 19 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 20 | using Microsoft.EntityFrameworkCore.Infrastructure; 21 | using EntityFrameworkCore.FirebirdSql.Metadata; 22 | using EntityFrameworkCore.FirebirdSql.Metadata.Internal; 23 | 24 | namespace Microsoft.EntityFrameworkCore 25 | { 26 | public static class FbPropertyBuilderExtensions 27 | { 28 | public static PropertyBuilder UseFirebirdIdentityColumn(this PropertyBuilder propertyBuilder) 29 | { 30 | GetFbInternalBuilder(propertyBuilder).ValueGenerationStrategy(FbValueGenerationStrategy.IdentityColumn); 31 | return propertyBuilder; 32 | } 33 | 34 | public static PropertyBuilder UseFirebirdIdentityColumn(this PropertyBuilder propertyBuilder) 35 | => (PropertyBuilder)UseFirebirdIdentityColumn((PropertyBuilder)propertyBuilder); 36 | 37 | public static PropertyBuilder UseFirebirdSequenceTrigger(this PropertyBuilder propertyBuilder) 38 | { 39 | GetFbInternalBuilder(propertyBuilder).ValueGenerationStrategy(FbValueGenerationStrategy.SequenceTrigger); 40 | return propertyBuilder; 41 | } 42 | 43 | public static PropertyBuilder UseFirebirdSequenceTrigger(this PropertyBuilder propertyBuilder) 44 | => (PropertyBuilder)UseFirebirdSequenceTrigger((PropertyBuilder)propertyBuilder); 45 | 46 | private static FbPropertyBuilderAnnotations GetFbInternalBuilder(PropertyBuilder propertyBuilder) 47 | => propertyBuilder.GetInfrastructure().Firebird(ConfigurationSource.Explicit); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbQueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq; 18 | using System.Linq.Expressions; 19 | using System.Reflection; 20 | 21 | namespace Microsoft.EntityFrameworkCore 22 | { 23 | public static class FbQueryableExtensions 24 | { 25 | internal static readonly MethodInfo WithLockMethodInfo 26 | = typeof(FbQueryableExtensions) 27 | .GetTypeInfo().GetDeclaredMethods(nameof(WithLock)) 28 | .Single(); 29 | 30 | public static IQueryable WithLock( 31 | this IQueryable source) 32 | where TEntity : class 33 | { 34 | return source.Provider.CreateQuery( 35 | Expression.Call( 36 | null, 37 | WithLockMethodInfo.MakeGenericMethod(typeof(TEntity)), 38 | source.Expression)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 18 | using EntityFrameworkCore.FirebirdSql.Internal; 19 | using EntityFrameworkCore.FirebirdSql.Metadata.Conventions; 20 | using EntityFrameworkCore.FirebirdSql.Migrations; 21 | using EntityFrameworkCore.FirebirdSql.Migrations.Internal; 22 | using EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal; 23 | using EntityFrameworkCore.FirebirdSql.Query.ExpressionVisitors.Internal; 24 | using EntityFrameworkCore.FirebirdSql.Query.Sql.Internal; 25 | using EntityFrameworkCore.FirebirdSql.Storage.Internal; 26 | using EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping; 27 | using EntityFrameworkCore.FirebirdSql.Update.Internal; 28 | using EntityFrameworkCore.FirebirdSql.ValueGeneration.Internal; 29 | using Microsoft.EntityFrameworkCore.Infrastructure; 30 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; 31 | using Microsoft.EntityFrameworkCore.Migrations; 32 | using Microsoft.EntityFrameworkCore.Query; 33 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 34 | using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors; 35 | using Microsoft.EntityFrameworkCore.Query.Sql; 36 | using Microsoft.EntityFrameworkCore.Storage; 37 | using Microsoft.EntityFrameworkCore.Update; 38 | using Microsoft.EntityFrameworkCore.Update.Internal; 39 | using Microsoft.EntityFrameworkCore.ValueGeneration; 40 | 41 | namespace Microsoft.Extensions.DependencyInjection 42 | { 43 | public static class FbServiceCollectionExtensions 44 | { 45 | public static IServiceCollection AddEntityFrameworkFirebird(this IServiceCollection serviceCollection) 46 | { 47 | var builder = new EntityFrameworkRelationalServicesBuilder(serviceCollection) 48 | .TryAdd() 49 | .TryAdd>() 50 | .TryAdd() 51 | .TryAdd() 52 | .TryAdd() 53 | .TryAdd() 54 | .TryAdd(p => p.GetService()) 55 | .TryAdd() 56 | .TryAdd() 57 | .TryAdd(p => p.GetService()) 58 | .TryAdd() 59 | .TryAdd() 60 | .TryAdd() 61 | .TryAdd() 62 | .TryAdd() 63 | .TryAdd() 64 | .TryAdd() 65 | .TryAdd(p => p.GetService()) 66 | .TryAdd() 67 | .TryAdd() 68 | .TryAddProviderSpecificServices(b => b 69 | .TryAddSingleton() 70 | .TryAddScoped() 71 | .TryAddScoped() 72 | .TryAddScoped()); 73 | 74 | builder.TryAddCoreServices(); 75 | return serviceCollection; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbSharedType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | // Copyright (c) .NET Foundation. All rights reserved. 18 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 19 | // Credit => https://github.com/ErikEJ/EntityFramework.SqlServerCompact/blob/master/src/Provider40/Utilities/SharedTypeExtensions.cs 20 | 21 | using System.Collections.Generic; 22 | using System.Diagnostics; 23 | using System.Linq; 24 | using System.Reflection; 25 | 26 | namespace System 27 | { 28 | [DebuggerStepThrough] 29 | internal static class SharedTypeExtensions 30 | { 31 | public static Type UnwrapNullableType(this Type type) => Nullable.GetUnderlyingType(type) ?? type; 32 | 33 | public static bool IsNullableType(this Type type) 34 | { 35 | var typeInfo = type.GetTypeInfo(); 36 | 37 | return !typeInfo.IsValueType 38 | || (typeInfo.IsGenericType 39 | && (typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))); 40 | } 41 | 42 | public static Type MakeNullable(this Type type) 43 | => type.IsNullableType() 44 | ? type 45 | : typeof(Nullable<>).MakeGenericType(type); 46 | 47 | public static bool IsInteger(this Type type) 48 | { 49 | type = type.UnwrapNullableType(); 50 | 51 | return (type == typeof(int)) 52 | || (type == typeof(long)) 53 | || (type == typeof(short)) 54 | || (type == typeof(byte)) 55 | || (type == typeof(uint)) 56 | || (type == typeof(ulong)) 57 | || (type == typeof(ushort)) 58 | || (type == typeof(sbyte)) 59 | || (type == typeof(char)); 60 | } 61 | 62 | public static bool IsIntegerForIdentity(this Type type) 63 | { 64 | type = type.UnwrapNullableType(); 65 | 66 | return (type == typeof(int)) 67 | || (type == typeof(long)); 68 | } 69 | 70 | public static Type UnwrapEnumType(this Type type) 71 | { 72 | var isNullable = type.IsNullableType(); 73 | type = isNullable ? type.UnwrapNullableType() : type; 74 | var underlyingEnumType = type.GetTypeInfo().IsEnum ? Enum.GetUnderlyingType(type) : type; 75 | return isNullable ? MakeNullable(underlyingEnumType) : underlyingEnumType; 76 | } 77 | 78 | public static Type TryGetElementType(this Type type, Type interfaceOrBaseType) 79 | { 80 | if (!type.GetTypeInfo().IsGenericTypeDefinition) 81 | { 82 | var types = GetGenericTypeImplementations(type, interfaceOrBaseType).ToArray(); 83 | 84 | return types.Length == 1 ? types[0].GetTypeInfo().GenericTypeArguments.FirstOrDefault() : null; 85 | } 86 | 87 | return null; 88 | } 89 | 90 | public static IEnumerable GetGenericTypeImplementations(this Type type, Type interfaceOrBaseType) 91 | { 92 | var typeInfo = type.GetTypeInfo(); 93 | if (!typeInfo.IsGenericTypeDefinition) 94 | { 95 | return (interfaceOrBaseType.GetTypeInfo().IsInterface 96 | ? typeInfo.ImplementedInterfaces 97 | : type.GetBaseTypes()) 98 | .Union(new[] { type }) 99 | .Where( 100 | t => t.GetTypeInfo().IsGenericType 101 | && (t.GetGenericTypeDefinition() == interfaceOrBaseType)); 102 | } 103 | 104 | return Enumerable.Empty(); 105 | } 106 | 107 | public static IEnumerable GetBaseTypes(this Type type) 108 | { 109 | type = type.GetTypeInfo().BaseType; 110 | 111 | while (type != null) 112 | { 113 | yield return type; 114 | type = type.GetTypeInfo().BaseType; 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/FbStringExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Extensions 20 | { 21 | public static class FbStringExtension 22 | { 23 | public static string MaxLength(this string src, int max) 24 | => src.Substring(0, Math.Min(src.Length, max)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Extensions/StringBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Collections.Generic; 18 | 19 | namespace System.Text 20 | { 21 | internal static class StringBuilderExtensions 22 | { 23 | public static StringBuilder AppendJoin(this StringBuilder stringBuilder, IEnumerable values, string separator = ", ") 24 | => stringBuilder.AppendJoin(values, (sb, value) => sb.Append(value), separator); 25 | 26 | public static StringBuilder AppendJoin(this StringBuilder stringBuilder, string separator, params string[] values) 27 | => stringBuilder.AppendJoin(values, (sb, value) => sb.Append(value), separator); 28 | 29 | public static StringBuilder AppendJoin( 30 | this StringBuilder stringBuilder, 31 | IEnumerable values, 32 | Action joinAction, 33 | string separator = ", ") 34 | { 35 | var appended = false; 36 | 37 | foreach (var value in values) 38 | { 39 | joinAction(stringBuilder, value); 40 | stringBuilder.Append(separator); 41 | appended = true; 42 | } 43 | 44 | if (appended) 45 | { 46 | stringBuilder.Length -= separator.Length; 47 | } 48 | 49 | return stringBuilder; 50 | } 51 | 52 | public static StringBuilder AppendJoin( 53 | this StringBuilder stringBuilder, 54 | IEnumerable values, TParam param, 55 | Action joinAction, 56 | string separator = ", ") 57 | { 58 | var appended = false; 59 | foreach (var value in values) 60 | { 61 | joinAction(stringBuilder, value, param); 62 | stringBuilder.Append(separator); 63 | appended = true; 64 | } 65 | 66 | if (appended) 67 | { 68 | stringBuilder.Length -= separator.Length; 69 | } 70 | 71 | return stringBuilder; 72 | } 73 | 74 | public static StringBuilder AppendJoinUpadate( 75 | this StringBuilder stringBuilder, 76 | IEnumerable values, TParam param, 77 | Action joinAction, 78 | string separator = ", ") 79 | { 80 | var appended = false; 81 | 82 | foreach (var value in values) 83 | { 84 | joinAction(stringBuilder, value, param); 85 | stringBuilder.Append(separator); 86 | appended = true; 87 | } 88 | 89 | if (appended) 90 | { 91 | stringBuilder.Length -= separator.Length; 92 | } 93 | 94 | return stringBuilder; 95 | } 96 | 97 | public static StringBuilder AppendJoin( 98 | this StringBuilder stringBuilder, 99 | IEnumerable values, TParam1 param1, 100 | TParam2 param2, 101 | Action joinAction, 102 | string separator = ", ") 103 | { 104 | var appended = false; 105 | 106 | foreach (var value in values) 107 | { 108 | joinAction(stringBuilder, value, param1, param2); 109 | stringBuilder.Append(separator); 110 | appended = true; 111 | } 112 | 113 | if (appended) 114 | { 115 | stringBuilder.Length -= separator.Length; 116 | } 117 | 118 | return stringBuilder; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Infrastructure/FbDbContextOptionsBuilder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.EntityFrameworkCore.Infrastructure; 19 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Infrastructure 22 | { 23 | public class FbDbContextOptionsBuilder : RelationalDbContextOptionsBuilder 24 | { 25 | public FbDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) 26 | : base(optionsBuilder) 27 | { } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Infrastructure/Internal/FbOptionsExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Infrastructure; 18 | using Microsoft.Extensions.DependencyInjection; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Infrastructure.Internal 21 | { 22 | public sealed class FbOptionsExtension : RelationalOptionsExtension 23 | { 24 | public FbOptionsExtension() 25 | { } 26 | 27 | public FbOptionsExtension(RelationalOptionsExtension copyFrom) 28 | : base(copyFrom) 29 | { } 30 | 31 | protected override RelationalOptionsExtension Clone() => new FbOptionsExtension(this); 32 | 33 | public override bool ApplyServices(IServiceCollection services) 34 | { 35 | services.AddEntityFrameworkFirebird(); 36 | return true; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Infrastructure/Internal/IFbOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Infrastructure; 18 | using System; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Infrastructure.Internal 21 | { 22 | public interface IFbOptions : ISingletonOptions 23 | { 24 | FbOptionsExtension Settings { get; } 25 | Version ServerVersion { get; } 26 | bool IsLegacyDialect { get; } 27 | int ObjectLengthName { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Internal/FbOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 19 | using Microsoft.EntityFrameworkCore.Infrastructure; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Internal 22 | { 23 | using Firebird = global::FirebirdSql.Data.FirebirdClient; 24 | using Data = global::FirebirdSql.Data.Services; 25 | public class FbOptions : IFbOptions 26 | { 27 | private bool IsLegacy { get; set; } 28 | public FbOptionsExtension Settings { get; private set; } 29 | public Version ServerVersion { get; private set; } 30 | public bool IsLegacyDialect 31 | { 32 | get 33 | { 34 | if (ServerVersion == null && Settings != null) 35 | { 36 | GetSettings(Settings.ConnectionString); 37 | } 38 | return IsLegacy; 39 | } 40 | set => IsLegacy = value; 41 | } 42 | 43 | public int ObjectLengthName 44 | => (ServerVersion ?? GetSettings(Settings.ConnectionString).ServerVersion).Major == 3 45 | ? 31 46 | : 63; 47 | 48 | public virtual void Initialize(IDbContextOptions options) => Settings = GetOptions(options); 49 | 50 | public virtual void Validate(IDbContextOptions options) => Settings = GetOptions(options); 51 | 52 | private FbOptionsExtension GetOptions(IDbContextOptions options) 53 | => options.FindExtension() ?? new FbOptionsExtension(); 54 | 55 | private FbOptions GetSettings(string connectionString) 56 | { 57 | if (string.IsNullOrWhiteSpace(connectionString)) 58 | { 59 | connectionString = Settings.Connection.ConnectionString; 60 | } 61 | if (ServerVersion != null) 62 | { 63 | return this; 64 | } 65 | 66 | try 67 | { 68 | IsLagacyDataBase(connectionString); 69 | } 70 | catch(Exception) 71 | { 72 | } 73 | return this; 74 | } 75 | 76 | private void IsLagacyDataBase(string connectionString) 77 | { 78 | try 79 | { 80 | using (var connection = new Firebird.FbConnection(connectionString)) 81 | { 82 | connection.Open(); 83 | ServerVersion = Data.FbServerProperties.ParseServerVersion(connection.ServerVersion); 84 | using (var cmd = connection.CreateCommand()) 85 | { 86 | cmd.CommandText = "SELECT MON$SQL_DIALECT FROM MON$DATABASE"; 87 | IsLegacy = Convert.ToInt32(cmd.ExecuteScalar()) == 1; 88 | } 89 | connection.Close(); 90 | } 91 | } 92 | finally 93 | { 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Conventions/FbConventionSetBuilder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Metadata.Conventions.Internal; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 20 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; 21 | using Microsoft.Extensions.DependencyInjection; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Conventions 24 | { 25 | public class FbConventionSetBuilder : RelationalConventionSetBuilder 26 | { 27 | public FbConventionSetBuilder(RelationalConventionSetBuilderDependencies dependencies) 28 | : base(dependencies) 29 | { } 30 | 31 | public override ConventionSet AddConventions(ConventionSet conventionSet) 32 | { 33 | base.AddConventions(conventionSet); 34 | 35 | var valueGenerationStrategyConvention = new FbValueGenerationStrategyConvention(); 36 | conventionSet.ModelInitializedConventions.Add(valueGenerationStrategyConvention); 37 | // ReplaceConvention(conventionSet.PropertyAddedConventions, (DatabaseGeneratedAttributeConvention)valueGenerationStrategyConvention); 38 | // ReplaceConvention(conventionSet.PropertyFieldChangedConventions, (DatabaseGeneratedAttributeConvention)valueGenerationStrategyConvention); 39 | return conventionSet; 40 | } 41 | 42 | public static ConventionSet Build() 43 | { 44 | var serviceProvider = new ServiceCollection() 45 | .AddEntityFrameworkFirebird() 46 | .AddDbContext(o => o.UseFirebird("DataSource=.")) 47 | .BuildServiceProvider(); 48 | 49 | using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) 50 | { 51 | using (var context = serviceScope.ServiceProvider.GetService()) 52 | { 53 | return ConventionSet.CreateConventionSet(context); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Conventions/Internal/FbValueGenerationStrategyConvention.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Metadata.Internal; 18 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; 19 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Conventions.Internal 22 | { 23 | public class FbValueGenerationStrategyConvention : IModelInitializedConvention 24 | { 25 | //public override InternalPropertyBuilder Apply( 26 | // InternalPropertyBuilder propertyBuilder, 27 | // DatabaseGeneratedAttributeConvention attribute, 28 | // MemberInfo clrMember) 29 | //{ 30 | // FbValueGenerationStrategy? valueGenerationStrategy = null; 31 | // var valueGenerated = ValueGenerated.Never; 32 | // if (attribute.DatabaseGeneratedOption == DatabaseGeneratedOption.Identity) 33 | // { 34 | // valueGenerated = ValueGenerated.OnAdd; 35 | // valueGenerationStrategy = FbValueGenerationStrategy.IdentityColumn; 36 | // } 37 | 38 | // propertyBuilder.ValueGenerated(valueGenerated, ConfigurationSource.Convention); 39 | // propertyBuilder.Firebird(ConfigurationSource.DataAnnotation).ValueGenerationStrategy(valueGenerationStrategy); 40 | // return base.Apply(propertyBuilder, attribute, clrMember); 41 | //} 42 | 43 | public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) 44 | { 45 | modelBuilder.Firebird(ConfigurationSource.Convention).ValueGenerationStrategy(FbValueGenerationStrategy.IdentityColumn); 46 | return modelBuilder; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/FbModelAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Metadata.Internal; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Metadata 21 | { 22 | public class FbModelAnnotations : RelationalModelAnnotations, IFbModelAnnotations 23 | { 24 | public FbModelAnnotations(IModel model) 25 | : base(model) 26 | { } 27 | 28 | protected FbModelAnnotations(RelationalAnnotations annotations) 29 | : base(annotations) 30 | { } 31 | 32 | public virtual FbValueGenerationStrategy? ValueGenerationStrategy 33 | { 34 | get => (FbValueGenerationStrategy?)Annotations.Metadata[FbAnnotationNames.ValueGenerationStrategy]; 35 | set => SetValueGenerationStrategy(value); 36 | } 37 | 38 | protected virtual bool SetValueGenerationStrategy(FbValueGenerationStrategy? value) 39 | => Annotations.SetAnnotation(FbAnnotationNames.ValueGenerationStrategy, value); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/FbValueGenerationStrategy.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | namespace EntityFrameworkCore.FirebirdSql.Metadata 18 | { 19 | public enum FbValueGenerationStrategy 20 | { 21 | None, 22 | IdentityColumn, 23 | SequenceTrigger 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/IFbModelAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Metadata 20 | { 21 | public interface IFbModelAnnotations : IRelationalModelAnnotations 22 | { 23 | FbValueGenerationStrategy? ValueGenerationStrategy { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/IFbPropertyAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Metadata 20 | { 21 | public interface IFbPropertyAnnotations : IRelationalPropertyAnnotations 22 | { 23 | FbValueGenerationStrategy? ValueGenerationStrategy { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Internal/FbAnnotationNames.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Internal 18 | { 19 | public static class FbAnnotationNames 20 | { 21 | public const string Prefix = "Fb:"; 22 | public const string ValueGenerationStrategy = Prefix + "ValueGenerationStrategy"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Internal/FbInternalMetadataBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Internal 20 | { 21 | public static class FbInternalMetadataBuilderExtensions 22 | { 23 | public static FbModelBuilderAnnotations Firebird(this InternalModelBuilder builder,ConfigurationSource configurationSource) 24 | => new FbModelBuilderAnnotations(builder, configurationSource); 25 | 26 | public static FbPropertyBuilderAnnotations Firebird( this InternalPropertyBuilder builder, ConfigurationSource configurationSource) 27 | => new FbPropertyBuilderAnnotations(builder, configurationSource); 28 | 29 | public static RelationalEntityTypeBuilderAnnotations Firebird(this InternalEntityTypeBuilder builder, ConfigurationSource configurationSource) 30 | => new RelationalEntityTypeBuilderAnnotations(builder, configurationSource); 31 | 32 | public static RelationalKeyBuilderAnnotations Firebird(this InternalKeyBuilder builder, ConfigurationSource configurationSource) 33 | => new RelationalKeyBuilderAnnotations(builder, configurationSource); 34 | 35 | public static RelationalIndexBuilderAnnotations Firebird(this InternalIndexBuilder builder, ConfigurationSource configurationSource) 36 | => new RelationalIndexBuilderAnnotations(builder, configurationSource); 37 | 38 | public static RelationalForeignKeyBuilderAnnotations Firebird(this InternalRelationshipBuilder builder, ConfigurationSource configurationSource) 39 | => new RelationalForeignKeyBuilderAnnotations(builder, configurationSource); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Internal/FbModelBuilderAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Internal 20 | { 21 | public class FbModelBuilderAnnotations : FbModelAnnotations 22 | { 23 | public FbModelBuilderAnnotations(InternalModelBuilder internalBuilder, ConfigurationSource configurationSource) 24 | : base(new RelationalAnnotationsBuilder(internalBuilder, configurationSource)) 25 | { } 26 | 27 | public new virtual bool ValueGenerationStrategy(FbValueGenerationStrategy? value) => SetValueGenerationStrategy(value); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Metadata/Internal/FbPropertyBuilderAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata.Internal; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Metadata.Internal 20 | { 21 | public class FbPropertyBuilderAnnotations : FbPropertyAnnotations 22 | { 23 | public FbPropertyBuilderAnnotations(InternalPropertyBuilder internalBuilder, ConfigurationSource configurationSource) 24 | : base(new RelationalAnnotationsBuilder(internalBuilder, configurationSource)) 25 | { } 26 | 27 | public new virtual bool ColumnName(string value) 28 | => SetColumnName(value); 29 | 30 | public new virtual bool ColumnType(string value) 31 | => SetColumnType(value); 32 | 33 | public new virtual bool DefaultValueSql(string value) 34 | => SetDefaultValueSql(value); 35 | 36 | public new virtual bool ComputedColumnSql(string value) 37 | => SetComputedColumnSql(value); 38 | 39 | public new virtual bool DefaultValue(object value) 40 | => SetDefaultValue(value); 41 | 42 | public new virtual bool ValueGenerationStrategy(FbValueGenerationStrategy? value) 43 | { 44 | if (!SetValueGenerationStrategy(value)) 45 | { 46 | return false; 47 | } 48 | return true; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/FbMigrationSqlGeneratorBehavior.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Migrations; 18 | using Microsoft.EntityFrameworkCore.Storage; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Migrations 21 | { 22 | public class FbMigrationSqlGeneratorBehavior : IFbMigrationSqlGeneratorBehavior 23 | { 24 | private readonly ISqlGenerationHelper _sqlHelper; 25 | 26 | public FbMigrationSqlGeneratorBehavior(ISqlGenerationHelper sqlHelper) 27 | => _sqlHelper = sqlHelper; 28 | 29 | private string SequenceName(string column, string table) 30 | => $"GEN_{column}_{table}"; 31 | 32 | private string TriggerName(string column, string table) 33 | => $"TRG_{column}_{table}"; 34 | 35 | public virtual void CreateIdentityForColumn( 36 | MigrationCommandListBuilder builder, 37 | string columnName, 38 | string tableName) 39 | { 40 | var sequenceName = SequenceName(columnName, tableName); 41 | var triggerName = TriggerName(columnName, tableName); 42 | 43 | builder.AppendLine("EXECUTE BLOCK"); 44 | builder.AppendLine("AS"); 45 | builder.AppendLine("BEGIN"); 46 | builder.Append("if (not exists(select 1 from rdb$generators where rdb$generator_name = '"); 47 | builder.Append(sequenceName); 48 | builder.Append("')) then"); 49 | builder.AppendLine(); 50 | builder.AppendLine("begin"); 51 | builder.Indent(); 52 | builder.Append("execute statement 'create sequence "); 53 | builder.Append(_sqlHelper.DelimitIdentifier(sequenceName)); 54 | builder.Append("';"); 55 | builder.DecrementIndent(); 56 | builder.AppendLine(); 57 | builder.AppendLine("end"); 58 | builder.AppendLine("END"); 59 | builder.EndCommand(); 60 | 61 | builder.Append("CREATE OR ALTER TRIGGER "); 62 | builder.Append(_sqlHelper.DelimitIdentifier(triggerName)); 63 | builder.Append(" ACTIVE BEFORE INSERT ON "); 64 | builder.Append(_sqlHelper.DelimitIdentifier(tableName)); 65 | builder.AppendLine(); 66 | builder.AppendLine("AS"); 67 | builder.AppendLine("BEGIN"); 68 | builder.Append("if (new."); 69 | builder.Append(_sqlHelper.DelimitIdentifier(columnName)); 70 | builder.Append(" is null) then"); 71 | builder.AppendLine(); 72 | builder.AppendLine("begin"); 73 | builder.Indent(); 74 | builder.Append("new."); 75 | builder.Append(_sqlHelper.DelimitIdentifier(columnName)); 76 | builder.Append(" = next value for "); 77 | builder.Append(_sqlHelper.DelimitIdentifier(sequenceName)); 78 | builder.Append(";"); 79 | builder.DecrementIndent(); 80 | builder.AppendLine(); 81 | builder.AppendLine("end"); 82 | builder.Append("END"); 83 | builder.EndCommand(); 84 | } 85 | 86 | public void DropIdentityForColumn( 87 | MigrationCommandListBuilder builder, 88 | string columnName, 89 | string tableName) 90 | { 91 | var triggerName = TriggerName(columnName, tableName); 92 | 93 | builder.AppendLine("EXECUTE BLOCK"); 94 | builder.AppendLine("AS"); 95 | builder.AppendLine("BEGIN"); 96 | builder.Indent(); 97 | builder.Append("if (exists(select 1 from rdb$triggers where rdb$trigger_name = '"); 98 | builder.Append(triggerName); 99 | builder.Append("')) then"); 100 | builder.AppendLine(); 101 | builder.AppendLine("begin"); 102 | builder.Indent(); 103 | builder.Append("execute statement 'drop trigger "); 104 | builder.Append(_sqlHelper.DelimitIdentifier(triggerName)); 105 | builder.Append("'"); 106 | builder.Append(_sqlHelper.StatementTerminator); 107 | builder.AppendLine(); 108 | builder.DecrementIndent(); 109 | builder.AppendLine("end"); 110 | builder.DecrementIndent(); 111 | builder.Append("END"); 112 | builder.EndCommand(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/IFbMigrationSqlGeneratorBehavior.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Migrations; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Migrations 20 | { 21 | public interface IFbMigrationSqlGeneratorBehavior 22 | { 23 | void CreateIdentityForColumn( 24 | MigrationCommandListBuilder builder, 25 | string columnName, 26 | string tableName); 27 | 28 | void DropIdentityForColumn( 29 | MigrationCommandListBuilder builder, 30 | string columnName, 31 | string tableName); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/Internal/FbHistoryRepository.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | //$Authors = Jiri Cincura (jiri@cincura.net), Rafael Almeida(ralms@ralms.net) 18 | 19 | using System; 20 | using Microsoft.EntityFrameworkCore; 21 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 22 | using Microsoft.EntityFrameworkCore.Migrations; 23 | using Microsoft.EntityFrameworkCore.Storage; 24 | 25 | namespace EntityFrameworkCore.FirebirdSql.Migrations.Internal 26 | { 27 | public class FbHistoryRepository : HistoryRepository 28 | { 29 | public FbHistoryRepository(HistoryRepositoryDependencies dependencies) 30 | : base(dependencies) 31 | { } 32 | 33 | protected override void ConfigureTable(EntityTypeBuilder history) 34 | { 35 | base.ConfigureTable(history); 36 | history.Property(h => h.MigrationId).HasColumnType("VARCHAR(95)"); 37 | history.Property(h => h.ProductVersion).HasColumnType("VARCHAR(32)").IsRequired(); 38 | } 39 | 40 | protected override string ExistsSql 41 | { 42 | get 43 | { 44 | var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); 45 | return $@" 46 | SELECT COUNT(*) 47 | FROM rdb$relations r 48 | WHERE 49 | COALESCE(r.rdb$system_flag, 0) = 0 50 | AND 51 | rdb$view_blr IS NULL 52 | AND 53 | rdb$relation_name = '{stringTypeMapping.GenerateSqlLiteral(TableName)}'"; 54 | } 55 | } 56 | 57 | protected override bool InterpretExistsResult(object value) => value != DBNull.Value; 58 | 59 | public override string GetCreateIfNotExistsScript() => GetCreateScript(); 60 | 61 | public override string GetBeginIfExistsScript(string migrationId) 62 | => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); 63 | 64 | public override string GetBeginIfNotExistsScript(string migrationId) 65 | => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); 66 | 67 | public override string GetEndIfScript() 68 | => throw new NotSupportedException("Generating idempotent scripts is currently not supported."); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/Internal/FbMigrationsAnnotationProvider.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Collections.Generic; 18 | using EntityFrameworkCore.FirebirdSql.Metadata.Internal; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.EntityFrameworkCore.Infrastructure; 21 | using Microsoft.EntityFrameworkCore.Metadata; 22 | using Microsoft.EntityFrameworkCore.Migrations; 23 | 24 | namespace EntityFrameworkCore.FirebirdSql.Migrations.Internal 25 | { 26 | public class FbMigrationsAnnotationProvider : MigrationsAnnotationProvider 27 | { 28 | public FbMigrationsAnnotationProvider(MigrationsAnnotationProviderDependencies dependencies) 29 | : base(dependencies) 30 | { } 31 | 32 | public override IEnumerable For(IProperty property) 33 | { 34 | if (property.Firebird().ValueGenerationStrategy.HasValue) 35 | { 36 | yield return new Annotation(FbAnnotationNames.ValueGenerationStrategy, property.Firebird().ValueGenerationStrategy); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/Operations/FbCreateDatabaseOperation.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using FirebirdSql.Data.FirebirdClient; 18 | using Microsoft.EntityFrameworkCore.Migrations.Operations; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Migrations.Operations 21 | { 22 | public class FbCreateDatabaseOperation : MigrationOperation 23 | { 24 | public virtual FbConnectionStringBuilder ConnectionStringBuilder { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Migrations/Operations/FbDropDatabaseOperation.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using FirebirdSql.Data.FirebirdClient; 18 | using Microsoft.EntityFrameworkCore.Migrations.Operations; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Migrations.Operations 21 | { 22 | public class FbDropDatabaseOperation : MigrationOperation 23 | { 24 | public virtual FbConnectionStringBuilder ConnectionStringBuilder { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Design; 2 | 3 | [assembly: DesignTimeProviderServices("EntityFrameworkCore.FirebirdSql.Design.Internal.FbDesignTimeServices")] 4 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/FbStrings.Designer.tt: -------------------------------------------------------------------------------- 1 | <# 2 | Session["ResourceFile"] = "FbStrings.resx"; 3 | #> 4 | <#@ include file="Resources.tt" #> -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/FirebirdSql.EntityFrameworkCore.Firebird.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL/05de1b824cc917bc45b2b2c1a2c318761b9b8bee/EFCore.FirebirdSql/Properties/FirebirdSql.EntityFrameworkCore.Firebird.snk -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/InternalsVisibleTo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("EFCore.FirebirdSql.FunctionalTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 7 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | Any CPU 10 | netstandard2.0 11 | bin\Debug\netstandard2.0\publish\ 12 | 13 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Properties/Resources.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbContainsOptimizedTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using System.Reflection; 19 | using Microsoft.EntityFrameworkCore.Query.Expressions; 20 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 23 | { 24 | public class FbContainsOptimizedTranslator : IMethodCallTranslator 25 | { 26 | private static readonly MethodInfo _methodInfo 27 | = typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) }); 28 | 29 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 30 | { 31 | if (!methodCallExpression.Method.Equals(_methodInfo)) 32 | { 33 | return null; 34 | } 35 | 36 | return Expression.GreaterThan( 37 | new SqlFunctionExpression("POSITION", typeof(int), new[] 38 | { 39 | methodCallExpression.Arguments[0], 40 | methodCallExpression.Object, 41 | }), 42 | Expression.Constant(0)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbConvertTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Linq.Expressions; 21 | using System.Reflection; 22 | using EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping; 23 | using Microsoft.EntityFrameworkCore.Query.Expressions; 24 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 25 | 26 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 27 | { 28 | public class FbConvertTranslator : IMethodCallTranslator 29 | { 30 | private static readonly Dictionary _typeMapping = new Dictionary 31 | { 32 | [nameof(Convert.ToByte)] = "SMALLINT", 33 | [nameof(Convert.ToDecimal)] = $"DECIMAL({FbTypeMappingSource.DefaultDecimalPrecision},{FbTypeMappingSource.DefaultDecimalScale})", 34 | [nameof(Convert.ToDouble)] = "DOUBLE PRECISION", 35 | [nameof(Convert.ToInt16)] = "SMALLINT", 36 | [nameof(Convert.ToInt32)] = "INTEGER", 37 | [nameof(Convert.ToInt64)] = "BIGINT", 38 | [nameof(Convert.ToString)] = $"VARCHAR({FbTypeMappingSource.VarcharMaxSize})" 39 | }; 40 | 41 | private static readonly HashSet _suportedTypes = new HashSet 42 | { 43 | typeof(bool), 44 | typeof(byte), 45 | typeof(decimal), 46 | typeof(double), 47 | typeof(float), 48 | typeof(int), 49 | typeof(long), 50 | typeof(short), 51 | typeof(string) 52 | }; 53 | 54 | private static readonly IEnumerable _supportedMethods 55 | = _typeMapping 56 | .Keys 57 | .SelectMany(t => typeof(Convert).GetTypeInfo() 58 | .GetDeclaredMethods(t) 59 | .Where(m => m.GetParameters().Length == 1 && _suportedTypes.Contains(m.GetParameters().First().ParameterType))); 60 | 61 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 62 | => _supportedMethods.Contains(methodCallExpression.Method) 63 | ? new ExplicitCastExpression(methodCallExpression.Arguments[0], methodCallExpression.Type) 64 | : null; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbDateAddTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Linq.Expressions; 21 | using System.Reflection; 22 | using Microsoft.EntityFrameworkCore.Query.Expressions; 23 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 24 | 25 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 26 | { 27 | public class FbDateAddTranslator : IMethodCallTranslator 28 | { 29 | private readonly Dictionary _methodInfoDatePartMapping = new Dictionary 30 | { 31 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddYears), new[] { typeof(int) }), "year" }, 32 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMonths), new[] { typeof(int) }), "month" }, 33 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddDays), new[] { typeof(double) }), "day" }, 34 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddHours), new[] { typeof(double) }), "hour" }, 35 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMinutes), new[] { typeof(double) }), "minute" }, 36 | { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddSeconds), new[] { typeof(double) }), "second" }, 37 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddYears), new[] { typeof(int) }), "year" }, 38 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMonths), new[] { typeof(int) }), "month" }, 39 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddDays), new[] { typeof(double) }), "day" }, 40 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddHours), new[] { typeof(double) }), "hour" }, 41 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMinutes), new[] { typeof(double) }), "minute" }, 42 | { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddSeconds), new[] { typeof(double) }), "second" }, 43 | }; 44 | 45 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 46 | { 47 | if (_methodInfoDatePartMapping.TryGetValue(methodCallExpression.Method, out var dateInfo)) 48 | { 49 | var amountToAdd = methodCallExpression.Arguments.First(); 50 | if (!dateInfo.Equals("year") 51 | && !dateInfo.Equals("month") 52 | && amountToAdd is ConstantExpression constantExpression 53 | && ((double)constantExpression.Value >= int.MaxValue 54 | || (double)constantExpression.Value <= int.MinValue)) 55 | { 56 | return null; 57 | } 58 | 59 | return new SqlFunctionExpression( 60 | functionName: "DATEADD", 61 | returnType: methodCallExpression.Type, 62 | arguments: new[] 63 | { 64 | new SqlFragmentExpression(dateInfo), 65 | amountToAdd, 66 | methodCallExpression.Object 67 | }); 68 | } 69 | 70 | return null; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbDateTimeMemberTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Linq.Expressions; 21 | using Microsoft.EntityFrameworkCore.Query.Expressions; 22 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 23 | 24 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 25 | { 26 | public class FbDateTimeMemberTranslator : IMemberTranslator 27 | { 28 | private static readonly Dictionary _datePartMapping 29 | = new Dictionary 30 | { 31 | { nameof(DateTime.Year), "year" }, 32 | { nameof(DateTime.Month), "month" }, 33 | { nameof(DateTime.DayOfYear), "dayofyear" }, 34 | { nameof(DateTime.Day), "day" }, 35 | { nameof(DateTime.Hour), "hour" }, 36 | { nameof(DateTime.Minute), "minute" }, 37 | { nameof(DateTime.Second), "second" }, 38 | { nameof(DateTime.Millisecond), "millisecond" }, 39 | { nameof(TimeSpan.TotalDays), "day" }, 40 | { nameof(TimeSpan.Days), "day" }, 41 | { nameof(TimeSpan.TotalHours), "hour" }, 42 | { nameof(TimeSpan.Hours), "hour" }, 43 | { nameof(TimeSpan.TotalMinutes), "minute" }, 44 | { nameof(TimeSpan.Minutes), "minute" }, 45 | { nameof(TimeSpan.TotalSeconds), "second" }, 46 | { nameof(TimeSpan.Seconds), "second" }, 47 | { nameof(TimeSpan.TotalMilliseconds), "millisecond" }, 48 | { nameof(TimeSpan.Milliseconds), "millisecond" }, 49 | }; 50 | 51 | public virtual Expression Translate(MemberExpression memberExpression) 52 | { 53 | var declaringType = memberExpression.Member.DeclaringType; 54 | var memberName = memberExpression.Member.Name; 55 | 56 | if (declaringType == typeof(TimeSpan) 57 | && memberExpression.Expression.NodeType == ExpressionType.Subtract) 58 | { 59 | var binaryExpression = memberExpression.Expression as BinaryExpression; 60 | if (_datePartMapping.TryGetValue(memberName, out var datePart)) 61 | { 62 | return new SqlFunctionExpression( 63 | functionName: "DATEDIFF", 64 | returnType: memberExpression.Type, 65 | arguments: new[] 66 | { 67 | new SqlFragmentExpression(datePart), 68 | binaryExpression.Left, 69 | binaryExpression.Right 70 | }); 71 | } 72 | } 73 | 74 | if (declaringType == typeof(DateTime) 75 | || declaringType == typeof(DateTimeOffset)) 76 | { 77 | if (_datePartMapping.TryGetValue(memberName, out var datePart)) 78 | { 79 | return new SqlFunctionExpression( 80 | functionName: "EXTRACT", 81 | returnType: memberExpression.Type, 82 | arguments: new[] 83 | { 84 | new SqlFragmentExpression(datePart), 85 | memberExpression.Expression 86 | }); 87 | 88 | } 89 | 90 | switch (memberName) 91 | { 92 | case nameof(DateTime.Now): 93 | case nameof(DateTime.UtcNow): 94 | return new ExplicitCastExpression( 95 | new SqlFragmentExpression("'NOW'"), 96 | memberExpression.Type); 97 | 98 | case nameof(DateTime.Today): 99 | return new SqlFunctionExpression( 100 | "CAST", 101 | memberExpression.Type, 102 | arguments: new[] 103 | { 104 | new SqlFragmentExpression("'TODAY'"), 105 | new SqlFragmentExpression("DATE") 106 | }); 107 | 108 | case nameof(DateTime.TimeOfDay): 109 | return new SqlFunctionExpression( 110 | "CAST", 111 | memberExpression.Type, 112 | arguments: new[] 113 | { 114 | memberExpression.Expression, 115 | new SqlFragmentExpression("TIME") 116 | }); 117 | } 118 | } 119 | 120 | return null; 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbEndsWithOptimizedTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using System.Reflection; 19 | using Microsoft.EntityFrameworkCore.Query.Expressions; 20 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 23 | { 24 | public class FbEndsWithOptimizedTranslator : IMethodCallTranslator 25 | { 26 | private static readonly MethodInfo _methodInfo = typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) }); 27 | 28 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 29 | { 30 | if (Equals(methodCallExpression.Method, _methodInfo)) 31 | { 32 | var patternExpression = methodCallExpression.Arguments[0]; 33 | 34 | var endsWithExpression = new NullCompensatedExpression( 35 | Expression.Equal( 36 | new SqlFunctionExpression( 37 | "RIGHT", 38 | methodCallExpression.Object.Type, 39 | new[] 40 | { 41 | methodCallExpression.Object, 42 | new SqlFunctionExpression("CHARACTER_LENGTH", typeof(int), new[] { patternExpression }) 43 | }), 44 | patternExpression)); 45 | 46 | return patternExpression is ConstantExpression patternConstantExpression 47 | ? (string)patternConstantExpression.Value == string.Empty 48 | ? (Expression)Expression.Constant(true) 49 | : endsWithExpression 50 | : Expression.OrElse( 51 | endsWithExpression, 52 | Expression.Equal(patternExpression, Expression.Constant(string.Empty))); 53 | } 54 | return null; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbNewGuidTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | 18 | using System; 19 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 22 | { 23 | public class FbNewGuidTranslator : SingleOverloadStaticMethodCallTranslator 24 | { 25 | public FbNewGuidTranslator() 26 | : base(typeof(Guid), nameof(Guid.NewGuid), "NEWID") 27 | { 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbObjectToStringTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Linq.Expressions; 21 | using Microsoft.EntityFrameworkCore.Query.Expressions; 22 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 23 | 24 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 25 | { 26 | public class FbObjectToStringTranslator : IMethodCallTranslator 27 | { 28 | static readonly List _supportedTypes = new List 29 | { 30 | typeof(int), 31 | typeof(long), 32 | typeof(DateTime), 33 | typeof(Guid), 34 | typeof(bool), 35 | typeof(byte), 36 | typeof(byte[]), 37 | typeof(double), 38 | typeof(DateTimeOffset), 39 | typeof(char), 40 | typeof(short), 41 | typeof(float), 42 | typeof(decimal), 43 | typeof(TimeSpan), 44 | typeof(uint), 45 | typeof(ushort), 46 | typeof(ulong), 47 | typeof(sbyte), 48 | }; 49 | 50 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 51 | => methodCallExpression.Method.Name == nameof(ToString) && 52 | methodCallExpression.Arguments.Count == 0 && 53 | methodCallExpression.Object != null && 54 | _supportedTypes.Contains(methodCallExpression.Object.Type.UnwrapNullableType().UnwrapEnumType()) 55 | ? new ExplicitCastExpression(methodCallExpression.Object, typeof(string)) 56 | : null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStartsWithOptimizedTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using System.Reflection; 19 | using Microsoft.EntityFrameworkCore.Query.Expressions; 20 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 23 | { 24 | public class FbStartsWithOptimizedTranslator : IMethodCallTranslator 25 | { 26 | private static readonly MethodInfo _methodStringOf = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) }); 27 | 28 | private static readonly MethodInfo _methodCharOf = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(char) }); 29 | 30 | static readonly MethodInfo _concatCast = typeof(string).GetRuntimeMethod(nameof(string.Concat), new[] { typeof(string), typeof(string) }); 31 | 32 | public virtual Expression Translate(MethodCallExpression methodStartCall) 33 | { 34 | if (!methodStartCall.Method.Equals(_methodStringOf) || 35 | !methodStartCall.Method.Equals(_methodCharOf) || 36 | methodStartCall.Object == null) 37 | return null; 38 | 39 | var constantPatternExpr = methodStartCall.Arguments[0] as ConstantExpression; 40 | if (methodStartCall != null) 41 | { 42 | // Operation Simple With LIKE Sample (LIKE 'FIREBIRD%') 43 | return new LikeExpression( 44 | methodStartCall.Object, 45 | Expression.Constant(System.Text.RegularExpressions.Regex.Replace((string)constantPatternExpr?.Value, @"([%_\\'])", @"\$1") + '%') 46 | ); 47 | } 48 | var pattern = methodStartCall.Arguments[0]; 49 | return Expression.AndAlso( 50 | new LikeExpression(methodStartCall.Object, Expression.Add(pattern, Expression.Constant("%"), _concatCast)), 51 | Expression.Equal(new SqlFunctionExpression("LEFT", typeof(string), new[] 52 | { 53 | methodStartCall.Object, 54 | new SqlFunctionExpression("CHARACTER_LENGTH", typeof(int), new[] { pattern }), 55 | }), 56 | pattern 57 | ) 58 | ); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringIsNullOrWhiteSpaceTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using System.Reflection; 19 | using Microsoft.EntityFrameworkCore.Query.Expressions; 20 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 23 | { 24 | public class FbStringIsNullOrWhiteSpaceTranslator : IMethodCallTranslator 25 | { 26 | private static readonly MethodInfo _methodInfo 27 | = typeof(string).GetRuntimeMethod(nameof(string.IsNullOrWhiteSpace), new[] { typeof(string) }); 28 | 29 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 30 | { 31 | if (methodCallExpression.Method.Equals(_methodInfo)) 32 | { 33 | var argument = methodCallExpression.Arguments[0]; 34 | 35 | return Expression.MakeBinary( 36 | ExpressionType.OrElse, 37 | new IsNullExpression(argument), 38 | Expression.Equal(new SqlFunctionExpression( 39 | "TRIM", 40 | typeof(string), 41 | new[] { argument }), 42 | Expression.Constant("", typeof(string)))); 43 | } 44 | return null; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringLengthTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using Microsoft.EntityFrameworkCore.Query.Expressions; 19 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 22 | { 23 | public class FbStringLengthTranslator : IMemberTranslator 24 | { 25 | public virtual Expression Translate(MemberExpression memberExpression) 26 | => memberExpression.Expression != null 27 | && memberExpression.Expression.Type == typeof(string) 28 | && memberExpression.Member.Name == nameof(string.Length) 29 | ? new SqlFunctionExpression("CHARACTER_LENGTH", memberExpression.Type, new[] { memberExpression.Expression }) 30 | : null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringReplaceTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq; 18 | using System.Linq.Expressions; 19 | using System.Reflection; 20 | using Microsoft.EntityFrameworkCore.Query.Expressions; 21 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 24 | { 25 | public class FbStringReplaceTranslator : IMethodCallTranslator 26 | { 27 | private static readonly MethodInfo _methodInfo 28 | = typeof(string).GetRuntimeMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) }); 29 | 30 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 31 | => _methodInfo.Equals(methodCallExpression.Method) 32 | ? new SqlFunctionExpression( 33 | "REPLACE", 34 | methodCallExpression.Type, 35 | new[] { methodCallExpression.Object }.Concat(methodCallExpression.Arguments)) 36 | : null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringSubstringTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using System.Reflection; 19 | using EntityFrameworkCore.FirebirdSql.Query.Expressions.Internal; 20 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 23 | { 24 | public class FbStringSubstringTranslator : IMethodCallTranslator 25 | { 26 | private static readonly MethodInfo _methodInfo 27 | = typeof(string).GetRuntimeMethod(nameof(string.Substring), new[] { typeof(int), typeof(int) }); 28 | 29 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 30 | { 31 | if (!_methodInfo.Equals(methodCallExpression.Method)) 32 | { 33 | return null; 34 | } 35 | 36 | var from = methodCallExpression.Arguments[0].NodeType == ExpressionType.Constant 37 | ? (Expression)Expression.Constant((int)((ConstantExpression)methodCallExpression.Arguments[0]).Value + 1) 38 | : Expression.Add(methodCallExpression.Arguments[0], Expression.Constant(1)); 39 | 40 | return new FbSubStringExpression( 41 | methodCallExpression.Object, 42 | from, 43 | methodCallExpression.Arguments[1]); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringToLowerTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 20 | { 21 | public class FbStringToLowerTranslator : ParameterlessInstanceMethodCallTranslator 22 | { 23 | public FbStringToLowerTranslator() 24 | : base(typeof(string), nameof(string.ToLower), "LOWER") 25 | { 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringToUpperTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 20 | { 21 | public class FbStringToUpperTranslator : ParameterlessInstanceMethodCallTranslator 22 | { 23 | public FbStringToUpperTranslator() 24 | : base(typeof(string), nameof(string.ToUpper), "UPPER") 25 | { 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionTranslators/Internal/FbStringTrimTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Linq.Expressions; 19 | using System.Reflection; 20 | using Microsoft.EntityFrameworkCore.Query.Expressions; 21 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 24 | { 25 | public class FbStringTrimTranslator : IMethodCallTranslator 26 | { 27 | private static readonly MethodInfo _methodInfoWithoutArgs 28 | = typeof(string).GetRuntimeMethod(nameof(string.Trim), new Type[] { }); 29 | 30 | private static readonly MethodInfo _methodInfoWithCharArrayArg 31 | = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char[]) }); 32 | 33 | public virtual Expression Translate(MethodCallExpression methodCallExpression) 34 | { 35 | if (_methodInfoWithoutArgs.Equals(methodCallExpression.Method) 36 | || _methodInfoWithCharArrayArg.Equals(methodCallExpression.Method) 37 | && ((methodCallExpression.Arguments[0] as ConstantExpression)?.Value as Array)?.Length == 0) 38 | { 39 | var sqlArguments = new[] { methodCallExpression.Object }; 40 | 41 | return new SqlFunctionExpression( 42 | "TRIM", 43 | methodCallExpression.Type, 44 | sqlArguments); 45 | } 46 | 47 | return null; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionVisitors/Internal/FbSqlTranslatingExpressionVisitor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * Jiri Cincura (juri@cincura.net) 4 | * 5 | * EntityFrameworkCore.FirebirdSql 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | * 16 | */ 17 | 18 | using System.Collections.Generic; 19 | using System.Linq.Expressions; 20 | using Microsoft.EntityFrameworkCore.Internal; 21 | using Microsoft.EntityFrameworkCore.Query; 22 | using Microsoft.EntityFrameworkCore.Query.Expressions; 23 | using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors; 24 | using Microsoft.EntityFrameworkCore.Storage; 25 | 26 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionVisitors.Internal 27 | { 28 | public class FbSqlTranslatingExpressionVisitor : SqlTranslatingExpressionVisitor 29 | { 30 | private static readonly HashSet _dateTimeDataTypes 31 | = new HashSet 32 | { 33 | "time", 34 | "date", 35 | "datetime", 36 | "timestamp" 37 | }; 38 | 39 | public FbSqlTranslatingExpressionVisitor( 40 | SqlTranslatingExpressionVisitorDependencies dependencies, 41 | RelationalQueryModelVisitor queryModelVisitor, 42 | SelectExpression targetSelectExpression = null, 43 | Expression topLevelPredicate = null, 44 | bool inProjection = false) 45 | : base(dependencies, queryModelVisitor, targetSelectExpression, topLevelPredicate, inProjection) 46 | { 47 | } 48 | 49 | protected override Expression VisitBinary(BinaryExpression binaryExpression) 50 | { 51 | var visitedExpression = base.VisitBinary(binaryExpression); 52 | 53 | if (visitedExpression == null) 54 | { 55 | return null; 56 | } 57 | 58 | switch (visitedExpression.NodeType) 59 | { 60 | case ExpressionType.Add: 61 | case ExpressionType.Subtract: 62 | case ExpressionType.Multiply: 63 | case ExpressionType.Divide: 64 | case ExpressionType.Modulo: 65 | return IsDateTimeBasedOperation(visitedExpression) 66 | ? null 67 | : visitedExpression; 68 | } 69 | 70 | return visitedExpression; 71 | } 72 | 73 | private static bool IsDateTimeBasedOperation(Expression expression) 74 | { 75 | if (expression is BinaryExpression binaryExpression) 76 | { 77 | var typeMapping = InferTypeMappingFromColumn(binaryExpression.Left) 78 | ?? InferTypeMappingFromColumn(binaryExpression.Right); 79 | 80 | if (typeMapping != null 81 | && _dateTimeDataTypes.Contains(typeMapping.StoreType)) 82 | { 83 | return true; 84 | } 85 | } 86 | 87 | return false; 88 | } 89 | 90 | private static RelationalTypeMapping InferTypeMappingFromColumn(Expression expression) 91 | => expression.FindProperty(expression.Type)?.FindRelationalMapping(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/ExpressionVisitors/Internal/FbSqlTranslatingExpressionVisitorFactory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * Jiri Cincura (juri@cincura.net) 4 | * 5 | * EntityFrameworkCore.FirebirdSql 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | * 16 | */ 17 | 18 | using System.Linq.Expressions; 19 | using Microsoft.EntityFrameworkCore.Query; 20 | using Microsoft.EntityFrameworkCore.Query.Expressions; 21 | using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionVisitors.Internal 24 | { 25 | public class FbSqlTranslatingExpressionVisitorFactory : SqlTranslatingExpressionVisitorFactory 26 | { 27 | public FbSqlTranslatingExpressionVisitorFactory( 28 | SqlTranslatingExpressionVisitorDependencies dependencies) 29 | : base(dependencies) 30 | { 31 | } 32 | 33 | public override SqlTranslatingExpressionVisitor Create( 34 | RelationalQueryModelVisitor queryModelVisitor, 35 | SelectExpression targetSelectExpression = null, 36 | Expression topLevelPredicate = null, 37 | bool inProjection = false) 38 | => new FbSqlTranslatingExpressionVisitor( 39 | Dependencies, queryModelVisitor, targetSelectExpression, topLevelPredicate, inProjection); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Expressions/Internal/FbExtractExpression.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | //$Authors = Jiri Cincura (jiri@cincura.net), Rafael Almeida(ralms@ralms.net) 18 | 19 | using System; 20 | using System.Linq.Expressions; 21 | using EntityFrameworkCore.FirebirdSql.Query.Sql.Internal; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.Expressions.Internal 24 | { 25 | public class FbExtractExpression : Expression 26 | { 27 | public virtual string Part { get; } 28 | public virtual Expression ValueExpression { get; } 29 | 30 | public FbExtractExpression(string part, Expression valueExpression) 31 | { 32 | Part = part; 33 | ValueExpression = valueExpression; 34 | } 35 | 36 | public override ExpressionType NodeType => ExpressionType.Extension; 37 | public override bool CanReduce => false; 38 | public override Type Type => typeof(int); 39 | 40 | protected override Expression Accept(ExpressionVisitor visitor) 41 | { 42 | if (visitor is IFbExpressionVisitor specificVisitor) 43 | { 44 | return specificVisitor.VisitExtract(this); 45 | } 46 | else 47 | { 48 | return base.Accept(visitor); 49 | } 50 | } 51 | 52 | protected override Expression VisitChildren(ExpressionVisitor visitor) 53 | { 54 | var newValueExpression = visitor.Visit(ValueExpression); 55 | 56 | return newValueExpression != ValueExpression 57 | ? new FbExtractExpression(Part, newValueExpression) 58 | : this; 59 | } 60 | 61 | public override bool Equals(object obj) 62 | { 63 | if (obj is null) 64 | { 65 | return false; 66 | } 67 | if (ReferenceEquals(this, obj)) 68 | { 69 | return true; 70 | } 71 | return obj.GetType() == GetType() && Equals((FbExtractExpression)obj); 72 | } 73 | 74 | public override int GetHashCode() 75 | { 76 | unchecked 77 | { 78 | var hashCode = Part.GetHashCode(); 79 | hashCode = (hashCode * 397) ^ ValueExpression.GetHashCode(); 80 | return hashCode; 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Expressions/Internal/FbStringExpression.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Linq.Expressions; 19 | using EntityFrameworkCore.FirebirdSql.Query.Sql.Internal; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Query.Expressions.Internal 22 | { 23 | public class FbSubStringExpression : Expression 24 | { 25 | public virtual Expression ValueExpression { get; } 26 | public virtual Expression FromExpression { get; } 27 | public virtual Expression ForExpression { get; } 28 | 29 | public FbSubStringExpression(Expression valueExpression, Expression fromExpression, Expression forExpression) 30 | { 31 | ValueExpression = valueExpression; 32 | FromExpression = fromExpression; 33 | ForExpression = forExpression; 34 | } 35 | 36 | public override ExpressionType NodeType => ExpressionType.Extension; 37 | public override bool CanReduce => false; 38 | public override Type Type => typeof(string); 39 | 40 | protected override Expression Accept(ExpressionVisitor visitor) 41 | { 42 | if (visitor is IFbExpressionVisitor specificVisitor) 43 | { 44 | return specificVisitor.VisitSubString(this); 45 | } 46 | else 47 | { 48 | return base.Accept(visitor); 49 | } 50 | } 51 | 52 | protected override Expression VisitChildren(ExpressionVisitor visitor) 53 | { 54 | var newValueExpression = visitor.Visit(ValueExpression); 55 | var newFromExpression = visitor.Visit(FromExpression); 56 | var newForExpression = visitor.Visit(ForExpression); 57 | 58 | return newValueExpression != ValueExpression 59 | || newFromExpression != FromExpression 60 | || newForExpression != ForExpression 61 | ? new FbSubStringExpression(newValueExpression, newFromExpression, newForExpression) 62 | : this; 63 | } 64 | 65 | public override bool Equals(object obj) 66 | { 67 | if (ReferenceEquals(null, obj)) 68 | { 69 | return false; 70 | } 71 | if (ReferenceEquals(this, obj)) 72 | { 73 | return true; 74 | } 75 | return obj.GetType() == GetType() && Equals((FbSubStringExpression)obj); 76 | } 77 | 78 | public override int GetHashCode() 79 | { 80 | unchecked 81 | { 82 | var hashCode = ValueExpression.GetHashCode(); 83 | hashCode = (hashCode * 397) ^ FromExpression.GetHashCode(); 84 | hashCode = (hashCode * 397) ^ ForExpression.GetHashCode(); 85 | return hashCode; 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/FbCompilationContextFactory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Query.Internal; 18 | using Microsoft.EntityFrameworkCore.Query.ResultOperators.Internal; 19 | 20 | namespace Microsoft.EntityFrameworkCore.Query 21 | { 22 | public class FbCompilationQueryableFactory : RelationalQueryCompilationContextFactory 23 | { 24 | public FbCompilationQueryableFactory( 25 | QueryCompilationContextDependencies dependencies, 26 | RelationalQueryCompilationContextDependencies relationalDependencies) 27 | : base(dependencies,relationalDependencies) 28 | { 29 | relationalDependencies 30 | .NodeTypeProviderFactory 31 | .RegisterMethods(WithLockExpressionNode.SupportedMethods, typeof(WithLockExpressionNode)); 32 | } 33 | 34 | public override QueryCompilationContext Create(bool async) 35 | => async 36 | ? new RelationalQueryCompilationContext( 37 | Dependencies, 38 | new AsyncLinqOperatorProvider(), 39 | new AsyncQueryMethodProvider(), 40 | TrackQueryResults) 41 | : new RelationalQueryCompilationContext( 42 | Dependencies, 43 | new LinqOperatorProvider(), 44 | new QueryMethodProvider(), 45 | TrackQueryResults); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/MethodsTranslators/FbCompositeMemberTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Linq; 19 | using System.Collections.Generic; 20 | using EntityFrameworkCore.FirebirdSql.Utilities; 21 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 24 | { 25 | public sealed class FbCompositeMemberTranslator : RelationalCompositeMemberTranslator 26 | { 27 | private static readonly List _translatorsMethods 28 | = TranslatorMethods.GetTranslatorMethods().ToList(); 29 | 30 | public FbCompositeMemberTranslator(RelationalCompositeMemberTranslatorDependencies dependencies) 31 | : base(dependencies) 32 | => AddTranslators(_translatorsMethods.Select(type => (IMemberTranslator)Activator.CreateInstance(type))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/MethodsTranslators/FbCompositeMethodCallTranslator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using EntityFrameworkCore.FirebirdSql.Utilities; 21 | using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Query.ExpressionTranslators.Internal 24 | { 25 | public sealed class FbCompositeMethodCallTranslator : RelationalCompositeMethodCallTranslator 26 | { 27 | private static readonly List _translatorsMethods 28 | = TranslatorMethods.GetTranslatorMethods().ToList(); 29 | 30 | public FbCompositeMethodCallTranslator(RelationalCompositeMethodCallTranslatorDependencies dependencies) 31 | : base(dependencies) 32 | => AddTranslators(_translatorsMethods.Select(type => (IMethodCallTranslator)Activator.CreateInstance(type))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Operators/WithLockExpressionNode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Collections.Generic; 18 | using System.Linq.Expressions; 19 | using System.Reflection; 20 | using Remotion.Linq.Clauses; 21 | using Remotion.Linq.Parsing.Structure.IntermediateModel; 22 | 23 | namespace Microsoft.EntityFrameworkCore.Query.ResultOperators.Internal 24 | { 25 | public class WithLockExpressionNode : ResultOperatorExpressionNodeBase 26 | { 27 | public static readonly IReadOnlyCollection SupportedMethods = new[] 28 | { FbQueryableExtensions.WithLockMethodInfo }; 29 | 30 | public WithLockExpressionNode( 31 | MethodCallExpressionParseInfo parseInfo, 32 | ConstantExpression WithLockExpressionExpression) 33 | : base(parseInfo, null, null) 34 | { 35 | } 36 | 37 | protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext) 38 | => new WithLockResultOperator(); 39 | 40 | public override Expression Resolve( 41 | ParameterExpression inputParameter, 42 | Expression expressionToBeResolved, 43 | ClauseGenerationContext clauseGenerationContext) 44 | => Source.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Operators/WithLockResultOperator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Linq.Expressions; 19 | using Remotion.Linq; 20 | using Remotion.Linq.Clauses; 21 | using Remotion.Linq.Clauses.ResultOperators; 22 | using Remotion.Linq.Clauses.StreamedData; 23 | 24 | namespace Microsoft.EntityFrameworkCore.Query.ResultOperators.Internal 25 | { 26 | public class WithLockResultOperator : SequenceTypePreservingResultOperatorBase, IQueryAnnotation 27 | { 28 | public virtual IQuerySource QuerySource { get; set; } 29 | public virtual QueryModel QueryModel { get; set; } 30 | public virtual string Hint => ToString(); 31 | public override ResultOperatorBase Clone(CloneContext cloneContext) 32 | => new WithLockResultOperator(); 33 | 34 | public override void TransformExpressions(Func transformation) 35 | { 36 | } 37 | 38 | public override StreamedSequence ExecuteInMemory(StreamedSequence input) 39 | => input; 40 | 41 | public override string ToString() => " WITH LOCK"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Sql/Internal/FbQuerySqlGeneratorFactory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 18 | using Microsoft.EntityFrameworkCore.Query.Expressions; 19 | using Microsoft.EntityFrameworkCore.Query.Sql; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Query.Sql.Internal 22 | { 23 | public class FbQuerySqlGeneratorFactory : QuerySqlGeneratorFactoryBase 24 | { 25 | private IFbOptions _fBOptions; 26 | public FbQuerySqlGeneratorFactory( 27 | QuerySqlGeneratorDependencies dependencies, 28 | IFbOptions fBOptions) 29 | : base(dependencies) => _fBOptions = fBOptions; 30 | 31 | public override IQuerySqlGenerator CreateDefault(SelectExpression selectExpression) 32 | => new FbQuerySqlGenerator(Dependencies, selectExpression, _fBOptions); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Query/Sql/Internal/IFbExpressionVisitor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Linq.Expressions; 18 | using EntityFrameworkCore.FirebirdSql.Query.Expressions.Internal; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Query.Sql.Internal 21 | { 22 | public interface IFbExpressionVisitor 23 | { 24 | Expression VisitExtract(FbExtractExpression extractExpression); 25 | Expression VisitSubString(FbSubStringExpression sbStringExpression); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Internal/FbDataReaderExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | // Copyright (c) .NET Foundation. All rights reserved. 18 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 19 | 20 | using System.Data.Common; 21 | 22 | namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal 23 | { 24 | /// 25 | /// This API supports the Entity Framework Core infrastructure and is not intended to be used 26 | /// directly from your code. This API may change or be removed in future releases. 27 | /// 28 | public static class SqlDataReaderExtension 29 | { 30 | /// 31 | /// This API supports the Entity Framework Core infrastructure and is not intended to be used 32 | /// directly from your code. This API may change or be removed in future releases. 33 | /// 34 | public static T GetValueOrDefault(this DbDataReader reader, string name) 35 | { 36 | var idx = reader.GetOrdinal(name); 37 | return reader.IsDBNull(idx) 38 | ? default 39 | : reader.GetFieldValue(idx); 40 | } 41 | 42 | /// 43 | /// This API supports the Entity Framework Core infrastructure and is not intended to be used 44 | /// directly from your code. This API may change or be removed in future releases. 45 | /// 46 | public static T GetValueOrDefault(this DbDataRecord record, string name) 47 | { 48 | var idx = record.GetOrdinal(name); 49 | return record.IsDBNull(idx) 50 | ? default 51 | : (T)record.GetValue(idx); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Internal/FbScaffoldingCodeGenerator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.EntityFrameworkCore.Design; 19 | using Microsoft.EntityFrameworkCore.Scaffolding; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Scaffolding.Internal 22 | { 23 | public class FbScaffoldingCodeGenerator : ProviderCodeGenerator 24 | { 25 | public FbScaffoldingCodeGenerator(ProviderCodeGeneratorDependencies dependencies) 26 | : base(dependencies) 27 | { 28 | } 29 | 30 | /// 31 | /// This API supports the Entity Framework Core infrastructure and is not intended to be used 32 | /// directly from your code. This API may change or be removed in future releases. 33 | /// 34 | public override MethodCallCodeFragment GenerateUseProvider( 35 | string connectionString, 36 | MethodCallCodeFragment providerOptions) 37 | { 38 | return new MethodCallCodeFragment( 39 | nameof(FbDbContextOptionsExtensions.UseFirebird), 40 | providerOptions == null 41 | ? new object[] { connectionString } 42 | : new object[] { connectionString, new NestedClosureCodeFragment("x", providerOptions) }); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Metadata/FbColumnModelAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Scaffolding.Metadata 20 | { 21 | public class FbDatabaseColumnAnnotations 22 | { 23 | private readonly DatabaseColumn _column; 24 | 25 | public FbDatabaseColumnAnnotations(DatabaseColumn column) => _column = column; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Metadata/FbDatabaseModelAnnotationNames.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | namespace EntityFrameworkCore.FirebirdSql.Scaffolding.Metadata 18 | { 19 | public class FbDatabaseModelAnnotationNames 20 | { 21 | public const string Prefix = "FbDatabaseModel:"; 22 | public const string Expression = Prefix + nameof(Expression); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Metadata/FbDatabaseModelExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Scaffolding.Metadata 20 | { 21 | public static class FbDatabaseModelExtensions 22 | { 23 | public static FbDatabaseColumnAnnotations Firebird(this DatabaseColumn column) 24 | => new FbDatabaseColumnAnnotations(column); 25 | 26 | public static FbIndexModelAnnotations Firebird(this DatabaseIndex index) 27 | => new FbIndexModelAnnotations(index); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Scaffolding/Metadata/FbIndexModelAnnotations.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Scaffolding.Metadata 20 | { 21 | public class FbIndexModelAnnotations 22 | { 23 | private readonly DatabaseIndex _index; 24 | 25 | public FbIndexModelAnnotations(DatabaseIndex index) => _index = index; 26 | 27 | public string Expression 28 | { 29 | get => _index[FbDatabaseModelAnnotationNames.Expression] as string; 30 | set => _index[FbDatabaseModelAnnotationNames.Expression] = value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/FbDatabaseCreator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * Jiri Cincura (jiri@cincura.net) 4 | * 5 | * EntityFrameworkCore.FirebirdSql 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | * 16 | */ 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using EntityFrameworkCore.FirebirdSql.Migrations.Operations; 21 | using Microsoft.EntityFrameworkCore.Migrations; 22 | using Microsoft.EntityFrameworkCore.Migrations.Operations; 23 | using FirebirdClientConnection = FirebirdSql.Data.FirebirdClient.FbConnection; 24 | using FirebirdSql.Data.FirebirdClient; 25 | using Microsoft.EntityFrameworkCore; 26 | using Microsoft.EntityFrameworkCore.Storage; 27 | 28 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 29 | { 30 | public class FbDatabaseCreator : RelationalDatabaseCreator 31 | { 32 | private readonly IFbRelationalConnection _connection; 33 | private readonly IRawSqlCommandBuilder _rawSqlCommandBuilder; 34 | 35 | public FbDatabaseCreator( 36 | RelationalDatabaseCreatorDependencies dependencies, 37 | IFbRelationalConnection connection, 38 | IRawSqlCommandBuilder rawSqlCommandBuilder) 39 | : base(dependencies) 40 | { 41 | _connection = connection; 42 | _rawSqlCommandBuilder = rawSqlCommandBuilder; 43 | } 44 | 45 | public override void Create() 46 | => Dependencies.MigrationCommandExecutor.ExecuteNonQuery(CreateDatabaseOperations(), _connection); 47 | 48 | public override void Delete() 49 | { 50 | FirebirdClientConnection.ClearAllPools(); 51 | FirebirdClientConnection.DropDatabase(_connection.ConnectionString); 52 | } 53 | 54 | public override bool Exists() 55 | { 56 | try 57 | { 58 | _connection.Open(); 59 | _connection.Close(); 60 | return true; 61 | } 62 | catch (FbException) 63 | { 64 | _connection?.Dispose(); 65 | return false; 66 | } 67 | } 68 | 69 | private IReadOnlyList CreateDatabaseOperations() 70 | { 71 | var operations = new MigrationOperation[] 72 | { 73 | new FbCreateDatabaseOperation 74 | { 75 | ConnectionStringBuilder = new FbConnectionStringBuilder(_connection.DbConnection.ConnectionString) 76 | } 77 | }; 78 | return Dependencies.MigrationsSqlGenerator.Generate(operations); 79 | } 80 | 81 | protected override bool HasTables() 82 | => Dependencies 83 | .ExecutionStrategyFactory.Create() 84 | .Execute(_connection, connection => Convert.ToInt32(CreateHasTablesCommand().ExecuteScalar(connection)) != 0); 85 | 86 | IRelationalCommand CreateHasTablesCommand() 87 | => _rawSqlCommandBuilder.Build("SELECT COUNT(*) FROM rdb$relations WHERE COALESCE(rdb$system_flag, 0) = 0 AND rdb$view_blr IS NULL"); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/FbRelationalCommand.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * Jiri Cincura (jiri@cincura.net) 4 | * 5 | * EntityFrameworkCore.FirebirdSql 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | * 16 | */ 17 | 18 | using System.Collections.Generic; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.EntityFrameworkCore.Diagnostics; 21 | using Microsoft.EntityFrameworkCore.Storage; 22 | using Microsoft.EntityFrameworkCore.Storage.Internal; 23 | 24 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 25 | { 26 | public class FirebirdRelationalCommand : RelationalCommand 27 | { 28 | public FirebirdRelationalCommand( 29 | IDiagnosticsLogger logger, 30 | string commandText, IReadOnlyList parameters) 31 | : base(logger, commandText, parameters) 32 | { 33 | } 34 | 35 | protected override object Execute( 36 | IRelationalConnection connection, 37 | DbCommandMethod executeMethod, 38 | IReadOnlyDictionary parameterValues) 39 | => ExecuteAsync(connection, executeMethod, parameterValues).GetAwaiter().GetResult(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/FbRelationalConnection.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Data.Common; 18 | using System.Threading.Tasks; 19 | using System.Data; 20 | using System.Threading; 21 | using System; 22 | using Microsoft.EntityFrameworkCore.Internal; 23 | using FirebirdSql.Data.FirebirdClient; 24 | using Microsoft.EntityFrameworkCore; 25 | using Microsoft.EntityFrameworkCore.Storage; 26 | 27 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 28 | { 29 | public class FbRelationalConnection : RelationalConnection, IFbRelationalConnection 30 | { 31 | public FbRelationalConnection(RelationalConnectionDependencies dependencies) 32 | : base(dependencies) 33 | { 34 | } 35 | 36 | protected override DbConnection CreateDbConnection() 37 | => new FbConnection(ConnectionString); 38 | 39 | public virtual IFbRelationalConnection CreateMasterConnection() 40 | { 41 | var csb = new FbConnectionStringBuilder(ConnectionString) 42 | { 43 | Pooling = false 44 | }; 45 | 46 | var contextOptions = new DbContextOptionsBuilder() 47 | .UseFirebird(csb.ConnectionString) 48 | .Options; 49 | 50 | return new FbRelationalConnection(Dependencies.With(contextOptions)); 51 | } 52 | 53 | public override bool IsMultipleActiveResultSetsEnabled => true; 54 | 55 | public override async Task BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default) 56 | { 57 | if (CurrentTransaction != null) 58 | { 59 | throw new InvalidOperationException(RelationalStrings.TransactionAlreadyStarted); 60 | } 61 | await OpenAsync(cancellationToken).ConfigureAwait(false); 62 | return BeginTransactionWithNoPreconditions(isolationLevel, cancellationToken); 63 | } 64 | 65 | private IDbContextTransaction BeginTransactionWithNoPreconditions(IsolationLevel isolationLevel, CancellationToken cancellationToken = default) 66 | { 67 | var dbTransaction = ((FbConnection)DbConnection).BeginTransaction(isolationLevel); 68 | CurrentTransaction = new FbRelationalTransaction(this, dbTransaction, Dependencies.TransactionLogger, true); 69 | Dependencies.TransactionLogger.TransactionStarted(this, dbTransaction, CurrentTransaction.TransactionId, DateTimeOffset.UtcNow); 70 | return CurrentTransaction; 71 | } 72 | 73 | public override IDbContextTransaction UseTransaction(DbTransaction transaction) 74 | { 75 | if (transaction == null) 76 | { 77 | if (CurrentTransaction != null) 78 | { 79 | CurrentTransaction = null; 80 | } 81 | } 82 | else 83 | { 84 | if (CurrentTransaction != null) 85 | { 86 | throw new InvalidOperationException(RelationalStrings.TransactionAlreadyStarted); 87 | } 88 | 89 | Open(); 90 | CurrentTransaction = new FbRelationalTransaction(this, transaction, Dependencies.TransactionLogger, transactionOwned: false); 91 | Dependencies.TransactionLogger.TransactionUsed(this, transaction, CurrentTransaction.TransactionId, DateTimeOffset.UtcNow); 92 | } 93 | return CurrentTransaction; 94 | } 95 | 96 | public virtual async Task CommitTransactionAsync(CancellationToken cancellationToken = default) 97 | { 98 | if (CurrentTransaction == null) 99 | { 100 | throw new InvalidOperationException(RelationalStrings.NoActiveTransaction); 101 | } 102 | await ((FbRelationalTransaction)CurrentTransaction).CommitAsync(cancellationToken).ConfigureAwait(false); 103 | } 104 | 105 | public virtual async Task RollbackTransactionAsync(CancellationToken cancellationToken = default) 106 | { 107 | if (CurrentTransaction == null) 108 | { 109 | throw new InvalidOperationException(RelationalStrings.NoActiveTransaction); 110 | } 111 | await ((FbRelationalTransaction)CurrentTransaction).RollbackAsync(cancellationToken).ConfigureAwait(false); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/FbRelationalTransaction.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Data.Common; 19 | using System.Diagnostics; 20 | using System.Threading; 21 | using System.Threading.Tasks; 22 | using Microsoft.EntityFrameworkCore.Diagnostics; 23 | using Microsoft.EntityFrameworkCore.Internal; 24 | using FirebirdSql.Data.FirebirdClient; 25 | using Microsoft.EntityFrameworkCore; 26 | using Microsoft.EntityFrameworkCore.Storage; 27 | 28 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 29 | { 30 | public class FbRelationalTransaction : RelationalTransaction 31 | { 32 | private readonly IRelationalConnection _relationalConnection; 33 | private readonly DbTransaction _dbTransaction; 34 | private readonly IDiagnosticsLogger _logger; 35 | private readonly bool _transactionOwned; 36 | 37 | public FbRelationalTransaction( 38 | IRelationalConnection connection, 39 | DbTransaction transaction, 40 | IDiagnosticsLogger logger, 41 | bool transactionOwned) 42 | : base(connection, transaction, logger, transactionOwned) 43 | { 44 | if (connection.DbConnection != transaction.Connection) 45 | { 46 | throw new InvalidOperationException(RelationalStrings.TransactionAssociatedWithDifferentConnection); 47 | } 48 | _relationalConnection = connection; 49 | _dbTransaction = transaction; 50 | _logger = logger; 51 | _transactionOwned = transactionOwned; 52 | } 53 | 54 | public virtual async Task CommitAsync(CancellationToken cancellationToken = default) 55 | { 56 | var startTime = DateTimeOffset.UtcNow; 57 | var stopwatch = Stopwatch.StartNew(); 58 | try 59 | { 60 | await Task.Run(() => (_dbTransaction as FbTransaction)?.Commit(), cancellationToken); 61 | _logger.TransactionCommitted(_relationalConnection, _dbTransaction, TransactionId, startTime, stopwatch.Elapsed); 62 | } 63 | catch (Exception e) 64 | { 65 | _logger 66 | .TransactionError(_relationalConnection, _dbTransaction, TransactionId, nameof(CommitAsync), e, startTime, stopwatch.Elapsed); 67 | throw; 68 | } 69 | 70 | ClearTransaction(); 71 | } 72 | 73 | public virtual async Task RollbackAsync(CancellationToken cancellationToken = default) 74 | { 75 | var startTime = DateTimeOffset.UtcNow; 76 | var stopwatch = Stopwatch.StartNew(); 77 | 78 | try 79 | { 80 | await Task.Run(() => (_dbTransaction as FbTransaction)?.Rollback(), cancellationToken); 81 | _logger 82 | .TransactionRolledBack(_relationalConnection, _dbTransaction, TransactionId, startTime, stopwatch.Elapsed); 83 | } 84 | catch (Exception e) 85 | { 86 | _logger 87 | .TransactionError(_relationalConnection, _dbTransaction, TransactionId, nameof(RollbackAsync), e, startTime, stopwatch.Elapsed); 88 | throw; 89 | } 90 | 91 | ClearTransaction(); 92 | } 93 | 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/FbSqlGeneratorHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Text; 18 | using EntityFrameworkCore.FirebirdSql.Extensions; 19 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 20 | using Microsoft.EntityFrameworkCore.Storage; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 23 | { 24 | public class FbSqlGenerationHelper : RelationalSqlGenerationHelper, IFbSqlGenerationHelper 25 | { 26 | private readonly IFbOptions _fbOptions; 27 | public string ParameterName { get; set; } 28 | private string Escape => (bool)_fbOptions?.IsLegacyDialect ? "" : "\""; 29 | 30 | public FbSqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependencies, IFbOptions options) 31 | : base(dependencies) 32 | { 33 | ParameterName = "@"; 34 | _fbOptions = options; 35 | } 36 | 37 | public override string EscapeIdentifier(string identifier) 38 | => identifier.MaxLength(_fbOptions.ObjectLengthName); 39 | 40 | public override void EscapeIdentifier(StringBuilder builder, string identifier) 41 | => builder.Append(identifier.MaxLength(_fbOptions.ObjectLengthName)); 42 | 43 | public override string DelimitIdentifier(string identifier) 44 | => $"{Escape}{EscapeIdentifier(identifier)}{Escape}"; 45 | 46 | public override void DelimitIdentifier(StringBuilder builder, string identifier) 47 | { 48 | builder.Append(Escape); 49 | EscapeIdentifier(builder, identifier.MaxLength(_fbOptions.ObjectLengthName)); 50 | builder.Append(Escape); 51 | } 52 | 53 | public override string GenerateParameterName(string name) 54 | => $"{ParameterName}{name.MaxLength(_fbOptions.ObjectLengthName)}"; 55 | 56 | public override void GenerateParameterName(StringBuilder builder, string name) 57 | => builder.Append(ParameterName).Append(name.MaxLength(_fbOptions.ObjectLengthName)); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/IFbRelationalConnection.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 20 | { 21 | public interface IFbRelationalConnection : IRelationalConnection 22 | { } 23 | } 24 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/IFbSqlGeneratorHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal 20 | { 21 | public interface IFbSqlGenerationHelper : ISqlGenerationHelper 22 | { 23 | string ParameterName { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbBoolTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Data.Common; 18 | using System.Reflection; 19 | using FirebirdSql.Data.FirebirdClient; 20 | using Microsoft.EntityFrameworkCore.Storage; 21 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 24 | { 25 | public class FbBoolTypeMapping : BoolTypeMapping 26 | { 27 | private static readonly MethodInfo _readMethod 28 | = typeof(FbDataReader).GetTypeInfo().GetDeclaredMethod(nameof(FbDataReader.GetBoolean)); 29 | 30 | private static CoreTypeMappingParameters _convert = 31 | new CoreTypeMappingParameters( 32 | typeof(bool), 33 | new ValueConverter( 34 | v => v ? 1 : 0, 35 | v => v.Equals(1))); 36 | 37 | public FbBoolTypeMapping(string storeType) 38 | : base( 39 | new RelationalTypeMappingParameters( 40 | _convert, 41 | storeType)) 42 | { 43 | } 44 | 45 | protected override void ConfigureParameter(DbParameter parameter) 46 | => ((FbParameter)parameter).FbDbType = FbDbType.SmallInt; 47 | 48 | protected override string GenerateNonNullSqlLiteral(object value) 49 | => ((value is int) 50 | ? (int)value == 1 51 | : (bool)value) ? "1" : "0"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbByteArrayTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using Microsoft.EntityFrameworkCore.Storage; 19 | 20 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 21 | { 22 | public class FbByteArrayTypeMapping : ByteArrayTypeMapping 23 | { 24 | public FbByteArrayTypeMapping() 25 | : base("BLOB SUB_TYPE BINARY", System.Data.DbType.Binary) 26 | { } 27 | 28 | protected override string GenerateNonNullSqlLiteral(object value) 29 | { 30 | var hex = BitConverter.ToString(((byte[])value)).Replace("-", string.Empty); 31 | return $"x'{hex}'"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbDateTimeTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using FirebirdSql.Data.FirebirdClient; 19 | using Microsoft.EntityFrameworkCore.Storage; 20 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 23 | { 24 | public class FbTimestampTypeMapping : FbTypeMapping 25 | { 26 | public FbTimestampTypeMapping() 27 | : base("TIMESTAMP", typeof(DateTime), FbDbType.TimeStamp) 28 | { } 29 | 30 | protected FbTimestampTypeMapping(RelationalTypeMappingParameters parameters, FbDbType fbDbType) 31 | : base(parameters, fbDbType) 32 | { } 33 | 34 | public override RelationalTypeMapping Clone(string storeType, int? size) 35 | => new FbTimestampTypeMapping(Parameters.WithStoreTypeAndSize(storeType, size), FbDbType); 36 | 37 | public override CoreTypeMapping Clone(ValueConverter converter) 38 | => new FbTimestampTypeMapping(Parameters.WithComposedConverter(converter), FbDbType); 39 | 40 | protected override string GenerateNonNullSqlLiteral(object value) 41 | => $"TIMESTAMP '{(DateTime)value:yyyy-MM-dd HH:mm:ss.fff}'"; 42 | } 43 | 44 | public class FbDateTypeMapping : FbTypeMapping 45 | { 46 | public FbDateTypeMapping() 47 | : base("DATE", typeof(DateTime), FbDbType.Date) 48 | { } 49 | 50 | protected FbDateTypeMapping(RelationalTypeMappingParameters parameters, FbDbType fbDbType) 51 | : base(parameters, fbDbType) 52 | { } 53 | 54 | public override RelationalTypeMapping Clone(string storeType, int? size) 55 | => new FbDateTypeMapping(Parameters.WithStoreTypeAndSize(storeType, size), FbDbType); 56 | 57 | public override CoreTypeMapping Clone(ValueConverter converter) 58 | => new FbDateTypeMapping(Parameters.WithComposedConverter(converter), FbDbType); 59 | 60 | protected override string GenerateNonNullSqlLiteral(object value) 61 | => $"DATE '{(DateTime)value:yyyy-MM-dd}'"; 62 | } 63 | 64 | public class FbTimeTypeMapping : FbTypeMapping 65 | { 66 | public FbTimeTypeMapping() 67 | : base("TIME", typeof(TimeSpan), FbDbType.Time) 68 | { } 69 | 70 | protected FbTimeTypeMapping(RelationalTypeMappingParameters parameters, FbDbType fbDbType) 71 | : base(parameters, fbDbType) 72 | { } 73 | 74 | public override RelationalTypeMapping Clone(string storeType, int? size) 75 | => new FbTimeTypeMapping(Parameters.WithStoreTypeAndSize(storeType, size), FbDbType); 76 | 77 | public override CoreTypeMapping Clone(ValueConverter converter) 78 | => new FbTimeTypeMapping(Parameters.WithComposedConverter(converter), FbDbType); 79 | 80 | protected override string GenerateNonNullSqlLiteral(object value) 81 | => $"TIME '{(TimeSpan)value:HH:mm:ss.fff}'"; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbGuidTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using FirebirdSql.Data.FirebirdClient; 18 | using System.Data.Common; 19 | using Microsoft.EntityFrameworkCore.Storage; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 22 | { 23 | public class FbGuidTypeMapping : GuidTypeMapping 24 | { 25 | public FbGuidTypeMapping() 26 | : base("CHAR(16) CHARACTER SET OCTETS") 27 | { } 28 | 29 | protected override void ConfigureParameter(DbParameter parameter) 30 | => ((FbParameter)parameter).FbDbType = FbDbType.Guid; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbStringTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System.Data.Common; 18 | using FirebirdSql.Data.FirebirdClient; 19 | using Microsoft.EntityFrameworkCore.Storage; 20 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 23 | { 24 | public class FbStringTypeMapping : StringTypeMapping 25 | { 26 | private readonly FbDbType _fbDbType; 27 | 28 | public FbStringTypeMapping(string storeType, FbDbType fbDbType, int? size = null) 29 | : base(storeType, unicode: true, size: size) 30 | => _fbDbType = fbDbType; 31 | 32 | protected override void ConfigureParameter(DbParameter parameter) 33 | => ((FbParameter)parameter).FbDbType = _fbDbType; 34 | 35 | protected FbStringTypeMapping(RelationalTypeMappingParameters parameters) 36 | : base(parameters) 37 | { 38 | } 39 | 40 | public override CoreTypeMapping Clone(ValueConverter converter) 41 | => new FbStringTypeMapping(Parameters.WithComposedConverter(converter)); 42 | 43 | public override RelationalTypeMapping Clone(string storeType, int? size) 44 | => new FbStringTypeMapping(Parameters.WithStoreTypeAndSize(storeType, size)); 45 | 46 | protected override string GenerateNonNullSqlLiteral(object value) 47 | => IsUnicode 48 | ? $"_UTF8'{EscapeSqlLiteral((string)value)}'" 49 | : $"'{EscapeSqlLiteral((string)value)}'"; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Storage/Internal/Mapping/FbTypeMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * Jiri Cincura (juri@cincura.net) 4 | * 5 | * EntityFrameworkCore.FirebirdSql 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | * 16 | */ 17 | 18 | using System; 19 | using System.Data.Common; 20 | using FirebirdSql.Data.FirebirdClient; 21 | using Microsoft.EntityFrameworkCore.Storage; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.Storage.Internal.Mapping 24 | { 25 | public abstract class FbTypeMapping : RelationalTypeMapping 26 | { 27 | public FbDbType FbDbType { get; } 28 | 29 | public FbTypeMapping( 30 | string storeType, 31 | Type clrType, 32 | FbDbType fbDbType) 33 | : base(storeType, clrType) 34 | => FbDbType = fbDbType; 35 | 36 | protected FbTypeMapping(RelationalTypeMappingParameters parameters, FbDbType fbDbType) 37 | : base(parameters) 38 | => FbDbType = fbDbType; 39 | 40 | protected override void ConfigureParameter(DbParameter parameter) 41 | { 42 | base.ConfigureParameter(parameter); 43 | 44 | ((FbParameter)parameter).FbDbType = FbDbType; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Update/Internal/FbBatchExecutor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Threading; 20 | using System.Threading.Tasks; 21 | using Microsoft.EntityFrameworkCore.Storage; 22 | using Microsoft.EntityFrameworkCore.Update; 23 | using EntityFrameworkCore.FirebirdSql.Storage.Internal; 24 | 25 | namespace EntityFrameworkCore.FirebirdSql.Update.Internal 26 | { 27 | public class FbBatchExecutor : IBatchExecutor 28 | { 29 | public int Execute(IEnumerable commandBatches, IRelationalConnection connection) 30 | { 31 | var recordAffecteds = 0; 32 | 33 | IDbContextTransaction currentTransaction = default; 34 | try 35 | { 36 | if (connection?.DbConnection?.State != System.Data.ConnectionState.Open) 37 | { 38 | connection.Open(); 39 | } 40 | 41 | if (connection.CurrentTransaction == null) 42 | { 43 | currentTransaction = connection.BeginTransaction(); 44 | } 45 | 46 | foreach (var commandbatch in commandBatches) 47 | { 48 | commandbatch.Execute(connection); 49 | recordAffecteds += commandbatch.ModificationCommands.Count; 50 | } 51 | currentTransaction?.Commit(); 52 | currentTransaction?.Dispose(); 53 | } 54 | catch (Exception ex) 55 | { 56 | currentTransaction?.Rollback(); 57 | currentTransaction?.Dispose(); 58 | 59 | throw ex; 60 | } 61 | finally 62 | { 63 | connection?.Close(); 64 | } 65 | return recordAffecteds; 66 | } 67 | 68 | public async Task ExecuteAsync( 69 | IEnumerable commandBatches, 70 | IRelationalConnection connection, 71 | CancellationToken cancellationToken = default) 72 | { 73 | var RowsAffecteds = 0; 74 | 75 | FbRelationalTransaction currentTransaction = null; 76 | try 77 | { 78 | if (connection?.DbConnection?.State != System.Data.ConnectionState.Open) 79 | { 80 | await connection.OpenAsync(cancellationToken, false).ConfigureAwait(false); 81 | } 82 | 83 | if (connection.CurrentTransaction == null) 84 | { 85 | currentTransaction = 86 | await ((FbRelationalConnection)connection) 87 | .BeginTransactionAsync(cancellationToken).ConfigureAwait(false) as FbRelationalTransaction; 88 | } 89 | 90 | foreach (var commandbatch in commandBatches) 91 | { 92 | await commandbatch.ExecuteAsync(connection, cancellationToken).ConfigureAwait(false); 93 | RowsAffecteds += commandbatch.ModificationCommands.Count; 94 | } 95 | 96 | if (currentTransaction != null) 97 | { 98 | await currentTransaction.CommitAsync(cancellationToken).ConfigureAwait(false); 99 | } 100 | 101 | currentTransaction?.Dispose(); 102 | } 103 | catch (Exception err) 104 | { 105 | currentTransaction?.Rollback(); 106 | currentTransaction?.Dispose(); 107 | 108 | throw err; 109 | } 110 | finally 111 | { 112 | connection?.Close(); 113 | } 114 | return RowsAffecteds; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Update/Internal/FbModificationCommandBatchFactory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Infrastructure; 18 | using Microsoft.EntityFrameworkCore.Storage; 19 | using Microsoft.EntityFrameworkCore.Update; 20 | 21 | namespace EntityFrameworkCore.FirebirdSql.Update.Internal 22 | { 23 | public class FbModificationCommandBatchFactory : IModificationCommandBatchFactory 24 | { 25 | private readonly IRelationalCommandBuilderFactory _commandBuilderFactory; 26 | private readonly ISqlGenerationHelper _sqlGenerationHelper; 27 | private readonly IFbUpdateSqlGenerator _updateSqlGenerator; 28 | private readonly IRelationalValueBufferFactoryFactory _valueBufferFactoryFactory; 29 | private readonly IDbContextOptions _options; 30 | 31 | public FbModificationCommandBatchFactory(IRelationalCommandBuilderFactory commandBuilderFactory, ISqlGenerationHelper sqlGenerationHelper, IFbUpdateSqlGenerator updateSqlGenerator, IRelationalValueBufferFactoryFactory valueBufferFactoryFactory, IDbContextOptions options) 32 | { 33 | _commandBuilderFactory = commandBuilderFactory; 34 | _sqlGenerationHelper = sqlGenerationHelper; 35 | _updateSqlGenerator = updateSqlGenerator; 36 | _valueBufferFactoryFactory = valueBufferFactoryFactory; 37 | _options = options; 38 | } 39 | 40 | public virtual ModificationCommandBatch Create() 41 | => new SingularModificationCommandBatch( 42 | _commandBuilderFactory, 43 | _sqlGenerationHelper, 44 | _updateSqlGenerator, 45 | _valueBufferFactoryFactory); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Update/Internal/IFbUpdateSqlGenerator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using Microsoft.EntityFrameworkCore.Update; 18 | 19 | namespace EntityFrameworkCore.FirebirdSql.Update.Internal 20 | { 21 | public interface IFbUpdateSqlGenerator : IUpdateSqlGenerator 22 | { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/Utilities/TranslatorMethods.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Reflection; 21 | 22 | namespace EntityFrameworkCore.FirebirdSql.Utilities 23 | { 24 | public class TranslatorMethods 25 | { 26 | public static IEnumerable GetTranslatorMethods() 27 | => Assembly 28 | .GetExecutingAssembly() 29 | .GetTypes().Where(t => 30 | t.GetInterfaces().Any(i => i == typeof(TInteface)) 31 | && t.GetConstructors().Any(c => c.GetParameters().Length == 0)); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/ValueGeneration/Internal/FbSequentialGuidValueGenerator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using System.Security.Cryptography; 19 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 20 | using Microsoft.EntityFrameworkCore.ChangeTracking; 21 | using Microsoft.EntityFrameworkCore.ValueGeneration; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.ValueGeneration.Internal 24 | { 25 | public class FbSequentialGuidValueGenerator : ValueGenerator 26 | { 27 | private readonly IFbOptions _options; 28 | private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create(); 29 | 30 | public FbSequentialGuidValueGenerator(IFbOptions options) 31 | { 32 | _options = options; 33 | } 34 | 35 | public override Guid Next(EntityEntry entry) 36 | { 37 | var randomBytes = new byte[8]; 38 | Rng.GetBytes(randomBytes); 39 | var ticks = (ulong)DateTime.UtcNow.Ticks * 2; 40 | var guidBytes = new byte[16]; 41 | var tickBytes = BitConverter.GetBytes(ticks); 42 | if (BitConverter.IsLittleEndian) 43 | { 44 | Array.Reverse(tickBytes); 45 | } 46 | Buffer.BlockCopy(tickBytes, 0, guidBytes, 0, 8); 47 | Buffer.BlockCopy(randomBytes, 0, guidBytes, 8, 8); 48 | return new Guid(guidBytes); 49 | } 50 | 51 | public override bool GeneratesTemporaryValues => false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /EFCore.FirebirdSql/ValueGeneration/Internal/FbValueGeneratorSelector.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 Rafael Almeida (ralms@ralms.net) 3 | * 4 | * EntityFrameworkCore.FirebirdSql 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | * 15 | */ 16 | 17 | using System; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | using Microsoft.EntityFrameworkCore.ValueGeneration; 20 | using EntityFrameworkCore.FirebirdSql.Infrastructure.Internal; 21 | using Microsoft.EntityFrameworkCore; 22 | 23 | namespace EntityFrameworkCore.FirebirdSql.ValueGeneration.Internal 24 | { 25 | public class FbValueGeneratorSelector : RelationalValueGeneratorSelector 26 | { 27 | private readonly IFbOptions _options; 28 | 29 | public FbValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies, IFbOptions options) 30 | : base(dependencies) 31 | => _options = options; 32 | 33 | public override ValueGenerator Create(IProperty property, IEntityType entityType) 34 | { 35 | var ret = property.ClrType.UnwrapNullableType() == typeof(Guid) 36 | ? property.ValueGenerated == ValueGenerated.Never 37 | || property.Firebird().DefaultValueSql != null 38 | ? (ValueGenerator)new TemporaryGuidValueGenerator() 39 | : new FbSequentialGuidValueGenerator(_options) 40 | : base.Create(property, entityType); 41 | return ret; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /EFCore.FirerbirdSql.ScaffoldTest/EFCore.FirerbirdSql.ScaffoldTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Exe 13 | netcoreapp2.1 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /EFCore.FirerbirdSql.ScaffoldTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EFCore.FirerbirdSql.ScaffoldTest 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Console.WriteLine("Hello World!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /EFCore.FirerbirdSql.ScaffoldTest/scaffold.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL/05de1b824cc917bc45b2b2c1a2c318761b9b8bee/EFCore.FirerbirdSql.ScaffoldTest/scaffold.ps1 -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### The issue 2 | 3 | Describe what is not working as expected. 4 | 5 | ### Steps to reproduce 6 | 7 | Ideally include a complete code listing that we can run to reproduce the issue. 8 | Alternatively, you can provide a project/solution that we can run. 9 | 10 | ### Error details 11 | 12 | If you are seeing an exception, include the full exceptions details (message and stack trace). 13 | 14 | ``` 15 | Exception message: 16 | Stack trace: 17 | ``` 18 | 19 | ### Further technical details 20 | 21 | Firebird version: 22 | EntityFrameworkCore.FirebirdSql version: 23 | 24 | Other details about my project setup: 25 | -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Efforts should be redirected to: 3 | https://github.com/cincuranet/FirebirdSql.Data.FirebirdClient 4 | 5 | EntityFrameworkCore.FirebirdSql for Firebird Server 6 | ===================== 7 | [![label](https://img.shields.io/github/issues-raw/badges/shields/website.svg?style=plastic)](https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSql) 8 | [![GitHub license](https://img.shields.io/badge/license-GPLv2-blue.svg)](https://raw.githubusercontent.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSql/master/LICENSE) [![Travis build status](https://img.shields.io/travis/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL.svg?label=travis-ci&branch=dev&style=plastic)](https://travis-ci.org/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL/branches) 9 | [![AppVeyor build status](https://img.shields.io/appveyor/ci/ralmsdeveloper/EntityFrameworkCore-FirebirdSQL/master.svg?label=appveyor&style=plastic)](https://ci.appveyor.com/project/ralmsdeveloper/entityframeworkcore-firebirdsql/branch/master) 10 | 11 | 12 | 13 | Provider | Package name | Stable (`master` branch) | On test (`dev` branch) 14 | -----------------------|-------------------------------------------|-----------------------------|------------------------- 15 | Firebird SQL | `EntityFrameworkCore.FirebirdSql` | [![NuGet](https://img.shields.io/nuget/v/EntityFrameworkCore.FirebirdSql.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/EntityFrameworkCore.FirebirdSql/) | [![NuGet](https://img.shields.io/nuget/vpre/EntityFrameworkCore.FirebirdSql.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/EntityFrameworkCore.FirebirdSql/) 16 | 17 | 18 | The EntityFrameworkCore.FirebirdSql is an Entity Framework Core access provider for Firebird SQL, compatible with version 3.X and earlier versions 2.x. 19 | 20 | Same uses the ADO.NET Library [Firebird Client](https://github.com/cincuranet/FirebirdSql.Data.FirebirdClient) written by friend Cincura. 21 | 22 | 23 | ## What we already have: 24 | All basic operations are working well 25 | 26 | Insert :heavy_check_mark: Update :heavy_check_mark: Delete :heavy_check_mark: 27 | 28 | Insert Bulk :heavy_check_mark: Update Bulk :heavy_check_mark: Delete Bulk :heavy_check_mark: 29 | 30 | Includes :heavy_check_mark: Complex Querys :heavy_check_mark: 31 | 32 | ## Supports: 33 | Guid, TimeStamp, Date, BigInt, Varchar, Text 34 | 35 | IDENTITY INCREMENT FOR FIREBIRD 3.X And 4.0 (Alpha) 36 | 37 | 38 | 39 | 40 | ## Example of use DBContext 41 | 42 | ```csharp 43 | //DataContext 44 | public class BlogContext : DbContext 45 | { 46 | 47 | public DbSet Blog { get; set; } 48 | public DbSet Posts { get; set; } 49 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 50 | { 51 | string connectionString = "..."; 52 | optionsBuilder.UseFirebird(connectionString); 53 | } 54 | protected override void OnModelCreating(ModelBuilder modelo) 55 | { 56 | //Fluent Api 57 | modelo.Entity(entity => 58 | { 59 | entity.HasIndex(e => e.BlogId) 60 | .HasName("Id") 61 | .IsUnique(); 62 | }); 63 | } 64 | } 65 | 66 | public class Blog 67 | { 68 | public int BlogId { get; set; } 69 | public string Url { get; set; } 70 | public List Posts { get; set; } 71 | } 72 | public class Post 73 | { 74 | public int PostId { get; set; } 75 | public string Title { get; set; } 76 | public string Content { get; set; } 77 | 78 | public int BlogId { get; set; } 79 | public Blog Blog { get; set; } 80 | } 81 | } 82 | ``` 83 | 84 | ## Example of use add 85 | ```csharp 86 | //Sample Use 87 | var cx = new BlogContext(); 88 | 89 | //one 90 | cx.Blog.Add(new Blog 91 | { 92 | Url = "https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSql" 93 | }); 94 | cx.SaveChanges(); 95 | 96 | //Range 97 | var RangeBlog = new List 98 | { 99 | new Blog{ Url="https://github.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSql" }, 100 | new Blog{ Url="https://github.com/ralmsdeveloper/" }, 101 | new Blog{ Url="https://blog.ralms.net" }, 102 | new Blog{ Url="https://ralms.net" } 103 | }; 104 | cx.Blog.AddRange(RangeBlog); 105 | cx.SaveChanges(); 106 | ``` 107 | 108 | ## Example of use update 109 | ```csharp 110 | //Sample Use 111 | var cx = new BlogContext(); 112 | 113 | var blog = cx.Blog.Find(1); 114 | cx.Attach(blog); 115 | blog.Url = "www.ralms.net"; 116 | cx.SaveChanges(); 117 | ``` 118 | 119 | ## Example of use delete 120 | ```csharp 121 | //Sample Use 122 | var cx = new BlogContext(); 123 | 124 | var blog = cx.Blog.Find(1); 125 | cx.Delete(blog); 126 | cx.SaveChanges(); 127 | ``` 128 | ## Example of use where 129 | ```csharp 130 | //Sample Use 131 | var cx = new BlogContext(); 132 | 133 | var blogs = cx.Blog.Where(p => p.BlogId > 0).ToList(); 134 | ``` 135 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '2.1.0.{build}' 2 | image: Visual Studio 2017 Preview 3 | configuration: 4 | - Debug 5 | environment: 6 | matrix: 7 | - name: FB 3.2 8 | fb_download: https://www.dropbox.com/s/4o6nvoahmlegv64/binarios.7z?dl=1 9 | cache: 10 | - '%USERPROFILE%\.nuget\packages -> **\*.csproj' 11 | shallow_clone: true 12 | install: 13 | - ps: $env:padded_build_number = $env:appveyor_build_number.PadLeft(5, '0') 14 | # Install .NET Core 2.0 15 | - ps: Invoke-WebRequest -Uri "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1" -OutFile "install-dotnet.ps1" 16 | - ps: .\install-dotnet.ps1 -Version 2.0.3 17 | test: off 18 | before_build: 19 | - ps: $baseDir = Resolve-Path . 20 | - dotnet --info 21 | - appveyor-retry dotnet restore -v Minimal 22 | build_script: 23 | - ps: $env:build_nuget = 'C:\Program Files\AppVeyor\BuildAgent\Tools\nuget.exe' 24 | after_build: 25 | - ps: mkdir "$baseDir\out" | Out-Null 26 | - ps: gci "$baseDir\out" | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } 27 | before_test: 28 | - ps: $testsBaseDir = "$baseDir\EFCore.FirebirdSql.FunctionalTests" 29 | - ps: mkdir C:\firebirdefcore | Out-Null 30 | - ps: cd C:\firebirdefcore 31 | - ps: Start-FileDownload "$env:fb_download" | Out-Null 32 | - ps: 7z x ($env:fb_download -replace '.+/([^/]+)\?dl=1','$1') 33 | - ps: .\firebird.exe -a 34 | test_script: 35 | - ps: cd $testsBaseDir 36 | - ps: dotnet restore 37 | - ps: dotnet test EFCore.FirebirdSql.FunctionalTests.csproj 38 | notifications: 39 | - provider: GitHubPullRequest 40 | on_build_success: true 41 | on_build_failure: true 42 | on_build_status_changed: true 43 | - provider: Email 44 | to: 45 | - ralms@ralms.net 46 | subject: EntityframeworkCore.FirebirdSql 47 | on_build_success: true 48 | on_build_failure: true 49 | on_build_status_changed: true 50 | -------------------------------------------------------------------------------- /msbuild.binlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ralmsdeveloper/EntityFrameworkCore.FirebirdSQL/05de1b824cc917bc45b2b2c1a2c318761b9b8bee/msbuild.binlog --------------------------------------------------------------------------------