├── .editorconfig
├── .gitattributes
├── .gitignore
├── License.md
├── README.md
├── References
├── EPPlus.XML
├── EPPlus.dll
├── ICSharpCode.AvalonEdit.dll
├── ICSharpCode.AvalonEdit.xml
├── Microsoft.WindowsAPICodePack.Shell.dll
├── Microsoft.WindowsAPICodePack.dll
├── MoonPdfLib.dll
├── MouseKeyboardActivityMonitor.dll
├── Newtonsoft.Json.dll
├── Newtonsoft.Json.xml
├── Oci
│ └── ODAC121024Xcopy_32bit.zip
├── Oracle.ManagedDataAccess.dll
├── Oracle.ManagedDataAccessDTC.dll
├── Oracle.ManagedDataAccessIOP.dll
├── Test
│ ├── Nito.AsyncEx.Enlightenment.dll
│ ├── Nito.AsyncEx.Enlightenment.xml
│ ├── Nito.AsyncEx.dll
│ ├── Nito.AsyncEx.xml
│ ├── Shouldly.dll
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
├── Xceed.Wpf.Toolkit.dll
├── Xceed.Wpf.Toolkit.xml
├── libmupdf.dll
├── protobuf-net.dll
└── protobuf-net.xml
├── SQLPad.nuspec
├── Screenshots
├── CodeComplete1.png
├── CodeComplete2.png
├── CodeComplete3.png
├── ColumnTooltip.png
├── DatabaseMonitor1.png
├── DatabaseOutput.png
├── ExecutionStatistics.png
├── ExpandAsterisk.png
├── FunctionOverloads.png
├── Overview1.png
├── Overview2.png
├── Overview3.png
├── Overview4.png
├── StatementExecutionHistory.png
├── TableTooltip.png
└── TraceEvents.png
├── SqlPad.Oracle.Database.Test
├── App.config
├── ConsoleTraceListenerTestFixture.cs
├── OracleConfiguration.xml
├── OracleDatabaseModelTest.cs
├── OracleDebuggerSessionTest.cs
├── Properties
│ └── AssemblyInfo.cs
└── SqlPad.Oracle.Database.Test.csproj
├── SqlPad.Oracle.Test
├── Commands
│ ├── CommandTest.cs
│ ├── FindUsagesCommandTest.cs
│ ├── OracleTestCommandSettingsProviderFactory.cs
│ └── TestCommandSettings.cs
├── ConsoleTraceListenerTestFixture.cs
├── MiscellaneousTest.cs
├── OracleCodeCompletionProviderTest.cs
├── OracleContextActionProviderTest.cs
├── OracleFoldingSectionProviderTest.cs
├── OracleMultiNodeEditorDataProviderTest.cs
├── OracleNavigationServiceTest.cs
├── OraclePlSqlStatementSemanticModelTest.cs
├── OraclePlSqlStatementValidatorTest.cs
├── OracleSnippetProviderTest.cs
├── OracleSqlParserTest.cs
├── OracleStatementFormatterTest.cs
├── OracleStatementSemanticModelTest.cs
├── OracleStatementValidatorTest.cs
├── OracleTestConnectionAdapter.cs
├── OracleTestDatabaseModel.cs
├── OracleTestInfrastructureFactory.cs
├── OracleTestObjectScriptExtractor.cs
├── OracleTokenReaderTest.cs
├── OracleToolTipProviderTest.cs
├── Properties
│ └── AssemblyInfo.cs
├── SqlPad.Oracle.Test.csproj
├── StatementGrammarNodeTest.cs
├── TestFiles
│ ├── SqlStatements1.sql
│ └── TestSnippet.xml
└── TestFixture.cs
├── SqlPad.Oracle
├── CodeCompletionSearchHelper.cs
├── CodeGenerationItems
│ ├── CreateFunction.xml
│ ├── CreatePackage.xml
│ ├── CreatePackageBody.xml
│ └── CreateProcedure.xml
├── Commands
│ ├── AddAliasCommand.cs
│ ├── AddCreateTableAsCommand.cs
│ ├── AddExpressionToClauseCommandBase.cs
│ ├── AddInsertIntoColumnListCommand.cs
│ ├── AddMissingColumnCommand.cs
│ ├── AddToGroupByCommand.cs
│ ├── AddToOrderByCommand.cs
│ ├── BindVariableLiteralConversionCommand.cs
│ ├── CleanRedundantSymbolCommand.cs
│ ├── ConfigureNamedParameterCommand.cs
│ ├── ConvertOrderByNumberColumnReferencesCommand.cs
│ ├── CreateScriptCommand.cs
│ ├── ExpandAsteriskCommand.cs
│ ├── ExpandViewCommand.cs
│ ├── ExtractPackageInterfaceCommand.cs
│ ├── FindUsagesCommand.cs
│ ├── GenerateCustomTypeCSharpWrapperClassCommand.cs
│ ├── LiteralBindVariableConversionCommand.cs
│ ├── ModifyCaseCommand.cs
│ ├── MoveContentCommand.cs
│ ├── OracleCommandBase.cs
│ ├── OracleCommandFactory.cs
│ ├── PropagateColumnCommand.cs
│ ├── ResolveAmbiguousColumnCommand.cs
│ ├── SafeDeleteCommand.cs
│ ├── SplitStringCommand.cs
│ ├── SqlTextBuilder.cs
│ ├── ToggleFullyQualifiedReferencesCommand.cs
│ ├── ToggleQuotedNotationCommand.cs
│ ├── UnnestInlineViewCommand.cs
│ ├── UnquoteCommand.cs
│ ├── WrapAsCommonTableExpressionCommand.cs
│ └── WrapAsInlineViewCommand.cs
├── CustomTypeCSharpWrapperClassGenerator.cs
├── DataDictionary
│ ├── OracleColumn.cs
│ ├── OracleConstraint.cs
│ ├── OracleDataDictionary.cs
│ ├── OracleDataType.cs
│ ├── OracleDatabaseLink.cs
│ ├── OracleObject.cs
│ ├── OracleObjectFactory.cs
│ ├── OracleObjectIdentifier.cs
│ ├── OracleProgramIdentifier.cs
│ ├── OracleProgramMetadata.cs
│ └── OracleReferenceBuilder.cs
├── DatabaseConnection
│ ├── OracleClobValue.cs
│ ├── OracleConnectionAdapter.cs
│ ├── OracleConnectionAdapterBase.cs
│ ├── OracleCustomTypeGenerator.cs
│ ├── OracleDataAccessExtensions.cs
│ ├── OracleDataDictionaryMapper.cs
│ ├── OracleDatabaseCommands.cs
│ ├── OracleDatabaseModel.cs
│ ├── OracleDatabaseModelBase.cs
│ ├── OracleDebugger.cs
│ └── OracleObjectScriptExtractor.cs
├── DebugTrace
│ ├── OracleTraceEvent.cs
│ ├── OracleTraceIdentifier.cs
│ ├── OracleTraceViewer.xaml
│ ├── OracleTraceViewer.xaml.cs
│ └── OracleTransientKernelProfile.cs
├── Documentation.Extensions.cs
├── Documentation.cs
├── Documentation.xsd
├── ExecutionPlan
│ ├── ExecutionPlanItem.cs
│ ├── ExecutionPlanItemCollection.cs
│ ├── ExecutionPlanTreeView.xaml
│ ├── ExecutionPlanTreeView.xaml.cs
│ ├── ExecutionPlanViewer.xaml
│ ├── ExecutionPlanViewer.xaml.cs
│ └── ExecutionStatisticsPlanItemCollection.cs
├── GenerateXsdClasses.cmd
├── ModelDataProviders
│ ├── CursorExecutionStatisticsDataProvider.cs
│ ├── ExplainPlanDataProvider.cs
│ ├── IModelDataProvider.cs
│ ├── ModelDataProvider.cs
│ ├── PartitionDataProvider.cs
│ ├── SessionExecutionStatisticsDataProvider.cs
│ ├── SqlMonitorDataProvider.cs
│ └── UserDataProvider.cs
├── OracleBindVariable.cs
├── OracleCodeCompletionItem.cs
├── OracleCodeCompletionProvider.cs
├── OracleCodeCompletionType.cs
├── OracleCommandSettingsProviderFactory.cs
├── OracleConditionValidator.cs
├── OracleConfiguration.Extensions.cs
├── OracleConfiguration.cs
├── OracleConfiguration.xml
├── OracleConfiguration.xsd
├── OracleContextActionProvider.cs
├── OracleDataExportConverter.cs
├── OracleDatabaseMonitor.cs
├── OracleDocumentation.xml
├── OracleExtensions.cs
├── OracleFoldingSectionProvider.cs
├── OracleGrammarDescription.cs
├── OracleGrammarDescription.tt
├── OracleHelpProvider.cs
├── OracleIdentifierValidationRule.cs
├── OracleInfrastructureFactory.cs
├── OracleMultiNodeEditorDataProvider.cs
├── OracleNavigationService.cs
├── OracleProgramMatcher.cs
├── OracleSemanticErrorType.cs
├── OracleSessionDetailViewer.xaml
├── OracleSessionDetailViewer.xaml.cs
├── OracleSnippetProvider.cs
├── OracleSqlGrammar.Extension.cs
├── OracleSqlGrammar.cs
├── OracleSqlGrammar.xml
├── OracleSqlGrammar.xsd
├── OracleSqlParser.cs
├── OracleStatement.cs
├── OracleStatementFormatter.cs
├── OracleStatementValidator.cs
├── OracleToken.cs
├── OracleTokenReader.cs
├── OracleValueAggregator.cs
├── Properties
│ └── AssemblyInfo.cs
├── Scripts
│ └── CreateExplainPlanTable.sql
├── SemanticModel
│ ├── OracleColumnBuilderVisitor.cs
│ ├── OracleColumnReference.cs
│ ├── OracleDataObjectReference.cs
│ ├── OracleDataTypeReference.cs
│ ├── OracleInsertTarget.cs
│ ├── OracleJoinDescription.cs
│ ├── OracleLiteral.cs
│ ├── OraclePivotTableReference.cs
│ ├── OraclePlSqlProgram.cs
│ ├── OraclePlSqlStatementSemanticModel.cs
│ ├── OracleProgramReference.cs
│ ├── OracleQueryBlock.cs
│ ├── OracleReference.cs
│ ├── OracleReferenceContainer.cs
│ ├── OracleReferenceDataSource.cs
│ ├── OracleSelectListColumn.cs
│ ├── OracleSequenceReference.cs
│ ├── OracleSpecialTableReference.cs
│ ├── OracleSqlModelReference.cs
│ ├── OracleStatementSemanticModel.cs
│ ├── OracleStatementSemanticModelFactory.cs
│ ├── OracleTableCollectionReference.cs
│ ├── QueryBlockType.cs
│ ├── ReferenceType.cs
│ └── StatementPlacement.cs
├── SessionActivityIndicator.xaml
├── SessionActivityIndicator.xaml.cs
├── SessionIdentifier.cs
├── Snippets
│ ├── SnippetGatherTableStats.xml
│ ├── SnippetInsert.xml
│ ├── SnippetObjects.xml
│ ├── SnippetSelect.xml
│ ├── SnippetSelectCount.xml
│ └── SnippetTables.xml
├── SqlPad.Oracle.csproj
├── Themes
│ ├── Common.xaml
│ ├── Generic.xaml
│ └── ToolTipDataGrid.xaml
└── ToolTips
│ ├── CircularProgresBarConverters.cs
│ ├── ConstraintList.xaml
│ ├── ConstraintList.xaml.cs
│ ├── IndexList.xaml
│ ├── IndexList.xaml.cs
│ ├── OracleToolTipBuilderVisitor.cs
│ ├── OracleToolTipProvider.cs
│ ├── PartitionDetailsModel.cs
│ ├── PartitionList.xaml
│ ├── PartitionList.xaml.cs
│ ├── PopupBase.cs
│ ├── ProfileDetails.xaml
│ ├── ProfileDetails.xaml.cs
│ ├── TablespaceDetails.xaml
│ ├── TablespaceDetails.xaml.cs
│ ├── ToolTipAsterisk.xaml
│ ├── ToolTipAsterisk.xaml.cs
│ ├── ToolTipColumn.xaml
│ ├── ToolTipColumn.xaml.cs
│ ├── ToolTipDatabaseLink.xaml
│ ├── ToolTipDatabaseLink.xaml.cs
│ ├── ToolTipMaterializedView.xaml
│ ├── ToolTipMaterializedView.xaml.cs
│ ├── ToolTipObject.xaml
│ ├── ToolTipObject.xaml.cs
│ ├── ToolTipPartition.xaml
│ ├── ToolTipPartition.xaml.cs
│ ├── ToolTipProgram.xaml
│ ├── ToolTipProgram.xaml.cs
│ ├── ToolTipSchema.xaml
│ ├── ToolTipSchema.xaml.cs
│ ├── ToolTipSequence.xaml
│ ├── ToolTipSequence.xaml.cs
│ ├── ToolTipTable.xaml
│ ├── ToolTipTable.xaml.cs
│ ├── ToolTipView.xaml
│ ├── ToolTipView.xaml.cs
│ ├── ToolTipViewColumn.xaml
│ └── ToolTipViewColumn.xaml.cs
├── SqlPad.Test
├── App.config
├── ConsoleTraceListenerTestFixture.cs
├── EditorNavigationServiceTest.cs
├── EditorTest.cs
├── MiscellaneousTest.cs
├── MultiNodeEditorTest.cs
├── Properties
│ └── AssemblyInfo.cs
├── SqlPad.Test.csproj
├── TemporaryDirectoryTestFixture.cs
├── TestFixture.cs
├── VisualComponentTest.cs
├── VisualTestRunner.cs
└── WorkDocumentTest.cs
├── SqlPad.sln
└── SqlPad
├── ActiveSnippet.cs
├── App.config
├── App.xaml
├── App.xaml.cs
├── Archive.ico
├── AssemblyBuildInfo.cs
├── BinaryDataHelper.cs
├── BindVariableModel.cs
├── Bookmarks
└── IconMargin.cs
├── CSharpQueryClassGenerator.cs
├── CellValueConverter.cs
├── Chart.ico
├── ClipboardManager.cs
├── ColumnHeader.cs
├── CommandSettingsModel.cs
├── Commands
├── CommandExecutionHandler.cs
├── ContextActionTextEditorCommand.cs
├── DiagnosticCommands.cs
├── GenericCommandHandler.cs
├── GenericCommands.cs
├── ICommandFactory.cs
└── ICommandSettings.cs
├── CompilationErrorArgs.cs
├── CompletionData.cs
├── ComplexTypeViewer.xaml
├── ComplexTypeViewer.xaml.cs
├── Configuration.Extensions.cs
├── Configuration.cs
├── Configuration.xml
├── Configuration.xsd
├── ConfigurationProvider.cs
├── DataExport
├── CsvDataExporter.cs
├── DataExportContextBase.cs
├── DataExportHelper.cs
├── ExcelDataExporter.cs
├── HtmlDataExporter.cs
├── IDataExporter.cs
├── JsonDataExporter.cs
├── MarkDownDataExporter.cs
├── SqlInsertDataExporter.cs
├── SqlUpdateDataExporter.cs
├── TsvDataExporter.cs
└── XmlDataExporter.cs
├── DataGridHelper.cs
├── DataGridResultViewer.xaml
├── DataGridResultViewer.xaml.cs
├── DataSpaceConverter.cs
├── DatabaseProviderConfiguration.cs
├── DebuggerViewer.xaml
├── DebuggerViewer.xaml.cs
├── DocumentPage.DependencyProperties.cs
├── DocumentPage.xaml
├── DocumentPage.xaml.cs
├── DragDrop
├── DragDropHelper.cs
├── DraggedAdorner.cs
└── InsertionAdorner.cs
├── EditDialog.xaml
├── EditDialog.xaml.cs
├── EditableTabHeaderControl.cs
├── EditorNavigationService.cs
├── EmptyIcon.ico
├── Extensions.cs
├── FileResultViewer.xaml
├── FileResultViewer.xaml.cs
├── FindReplace
├── Adapters.cs
├── FindReplace.cs
├── FindReplaceDialog.xaml
├── FindReplaceDialog.xaml.cs
├── IEditor.cs
├── TextSearchHelper.cs
├── next.png
└── prev.png
├── FoldingSection.cs
├── GenerateXsdClasses.cmd
├── ICodeCompletionProvider.cs
├── ICodeSnippetProvider.cs
├── IConnectionAdapter.cs
├── IContextActionProvider.cs
├── IDatabaseModel.cs
├── IDebuggerSession.cs
├── IHelpProvider.cs
├── IInfrastructureFactory.cs
├── ILargeTextValue.cs
├── ISqlParser.cs
├── IStatementFormatter.cs
├── IStatementValidator.cs
├── IToken.cs
├── ITokenReader.cs
├── IToolTipProvider.cs
├── IValidationModel.cs
├── InfrastructureConfigurationSection.cs
├── JavaScriptSyntaxHighlight.xshd
├── LargeValueEditor.xaml
├── LargeValueEditor.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── MarginSetter.cs
├── Messages.cs
├── MetadataCache.cs
├── ModelBase.cs
├── ModificationNotification
└── ModificationNotificationMargin.cs
├── MultiNodeEditor.cs
├── Namespaces.cs
├── NodeType.cs
├── OutputViewer.DependencyProperties.cs
├── OutputViewer.xaml
├── OutputViewer.xaml.cs
├── ParseResult.cs
├── ParseStatus.cs
├── PasswordDialog.xaml
├── PasswordDialog.xaml.cs
├── ProgramOverloadList.xaml
├── ProgramOverloadList.xaml.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── Resources.cs
├── ResultInfo.cs
├── ResultSetDataGridTemplateSelector.cs
├── ScrollingTextBox.cs
├── SearchTextBox.cs
├── Snippet.cs
├── Snippet.xsd
├── Snippets.cs
├── SourcePosition.cs
├── SqlDocumentColorizingTransformer.cs
├── SqlDocumentRepository.cs
├── SqlEditor.xaml
├── SqlEditor.xaml.cs
├── SqlEditorBackgroundRenderer.cs
├── SqlFoldingStrategy.cs
├── SqlPad.csproj
├── SqlPad.ico
├── SqlPadTextBox.cs
├── SqlTextEditor.cs
├── StatementBase.cs
├── StatementCollection.cs
├── StatementCommentNode.cs
├── StatementExecutionHistory.xaml
├── StatementExecutionHistory.xaml.cs
├── StatementExecutionModel.cs
├── StatementGrammarNode.cs
├── StatementNode.cs
├── StatusInfoModel.cs
├── TextHelper.cs
├── TextSegment.cs
├── TraceLog.cs
├── WindowClipboardHistory.xaml
├── WindowClipboardHistory.xaml.cs
├── WindowDatabaseMonitor.xaml
├── WindowDatabaseMonitor.xaml.cs
├── WindowOperationMonitor.xaml
├── WindowOperationMonitor.xaml.cs
├── WindowTraceLog.xaml
├── WindowTraceLog.xaml.cs
├── WorkDocument.cs
├── WorkDocumentCollection.cs
└── WpfExtensions.cs
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; Top-most EditorConfig file
2 | root = true
3 |
4 | [*.cs]
5 | indent_style = tab
6 | indent_size = 4
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Jan Hucka
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
--------------------------------------------------------------------------------
/References/EPPlus.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/EPPlus.dll
--------------------------------------------------------------------------------
/References/ICSharpCode.AvalonEdit.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/ICSharpCode.AvalonEdit.dll
--------------------------------------------------------------------------------
/References/Microsoft.WindowsAPICodePack.Shell.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Microsoft.WindowsAPICodePack.Shell.dll
--------------------------------------------------------------------------------
/References/Microsoft.WindowsAPICodePack.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Microsoft.WindowsAPICodePack.dll
--------------------------------------------------------------------------------
/References/MoonPdfLib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/MoonPdfLib.dll
--------------------------------------------------------------------------------
/References/MouseKeyboardActivityMonitor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/MouseKeyboardActivityMonitor.dll
--------------------------------------------------------------------------------
/References/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/References/Oci/ODAC121024Xcopy_32bit.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Oci/ODAC121024Xcopy_32bit.zip
--------------------------------------------------------------------------------
/References/Oracle.ManagedDataAccess.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Oracle.ManagedDataAccess.dll
--------------------------------------------------------------------------------
/References/Oracle.ManagedDataAccessDTC.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Oracle.ManagedDataAccessDTC.dll
--------------------------------------------------------------------------------
/References/Oracle.ManagedDataAccessIOP.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Oracle.ManagedDataAccessIOP.dll
--------------------------------------------------------------------------------
/References/Test/Nito.AsyncEx.Enlightenment.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Test/Nito.AsyncEx.Enlightenment.dll
--------------------------------------------------------------------------------
/References/Test/Nito.AsyncEx.Enlightenment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Nito.AsyncEx.Enlightenment
5 |
6 |
7 |
8 |
9 | Verifies platform enlightenment.
10 |
11 |
12 |
13 |
14 | Returns a value indicating whether the correct platform enlightenment provider has been loaded.
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/References/Test/Nito.AsyncEx.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Test/Nito.AsyncEx.dll
--------------------------------------------------------------------------------
/References/Test/Shouldly.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Test/Shouldly.dll
--------------------------------------------------------------------------------
/References/Test/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Test/nunit.framework.dll
--------------------------------------------------------------------------------
/References/Xceed.Wpf.Toolkit.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/Xceed.Wpf.Toolkit.dll
--------------------------------------------------------------------------------
/References/libmupdf.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/libmupdf.dll
--------------------------------------------------------------------------------
/References/protobuf-net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/References/protobuf-net.dll
--------------------------------------------------------------------------------
/Screenshots/CodeComplete1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/CodeComplete1.png
--------------------------------------------------------------------------------
/Screenshots/CodeComplete2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/CodeComplete2.png
--------------------------------------------------------------------------------
/Screenshots/CodeComplete3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/CodeComplete3.png
--------------------------------------------------------------------------------
/Screenshots/ColumnTooltip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/ColumnTooltip.png
--------------------------------------------------------------------------------
/Screenshots/DatabaseMonitor1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/DatabaseMonitor1.png
--------------------------------------------------------------------------------
/Screenshots/DatabaseOutput.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/DatabaseOutput.png
--------------------------------------------------------------------------------
/Screenshots/ExecutionStatistics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/ExecutionStatistics.png
--------------------------------------------------------------------------------
/Screenshots/ExpandAsterisk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/ExpandAsterisk.png
--------------------------------------------------------------------------------
/Screenshots/FunctionOverloads.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/FunctionOverloads.png
--------------------------------------------------------------------------------
/Screenshots/Overview1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/Overview1.png
--------------------------------------------------------------------------------
/Screenshots/Overview2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/Overview2.png
--------------------------------------------------------------------------------
/Screenshots/Overview3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/Overview3.png
--------------------------------------------------------------------------------
/Screenshots/Overview4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/Overview4.png
--------------------------------------------------------------------------------
/Screenshots/StatementExecutionHistory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/StatementExecutionHistory.png
--------------------------------------------------------------------------------
/Screenshots/TableTooltip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/TableTooltip.png
--------------------------------------------------------------------------------
/Screenshots/TraceEvents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/Screenshots/TraceEvents.png
--------------------------------------------------------------------------------
/SqlPad.Oracle.Database.Test/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Database.Test/ConsoleTraceListenerTestFixture.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using NUnit.Framework;
3 |
4 | namespace SqlPad.Oracle.Database.Test
5 | {
6 | [SetUpFixture]
7 | public class ConsoleTraceListenerTestFixture
8 | {
9 | [OneTimeSetUp]
10 | public void SetUp()
11 | {
12 | Trace.Listeners.Add(new ConsoleTraceListener());
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Database.Test/OracleConfiguration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | C:\Oracle\product\12.1.0\dbhome_1\BIN\tkprof.exe
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Database.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("SqlPad.Oracle.Database.Test")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("SqlPad.Oracle.Database.Test")]
12 | [assembly: AssemblyCopyright("Copyright © 2016")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("5517bbaf-6f68-4c3f-aefc-b3670adba9a9")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/Commands/OracleTestCommandSettingsProviderFactory.cs:
--------------------------------------------------------------------------------
1 | using SqlPad.Commands;
2 |
3 | namespace SqlPad.Oracle.Test.Commands
4 | {
5 | internal class OracleTestCommandSettingsProviderFactory : ICommandSettingsProviderFactory
6 | {
7 | public ICommandSettingsProvider CreateCommandSettingsProvider(CommandSettingsModel settings)
8 | {
9 | return new TestCommandSettings(settings);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/Commands/TestCommandSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SqlPad.Commands;
3 |
4 | namespace SqlPad.Oracle.Test.Commands
5 | {
6 | internal class TestCommandSettings : ICommandSettingsProvider
7 | {
8 | private readonly bool _isValueValid;
9 |
10 | public TestCommandSettings(CommandSettingsModel settingsModel, bool isValueValid = true)
11 | {
12 | Settings = settingsModel;
13 | _isValueValid = isValueValid;
14 | }
15 |
16 | public EventHandler GetSettingsCalled;
17 |
18 | public bool GetSettings()
19 | {
20 | GetSettingsCalled?.Invoke(this, EventArgs.Empty);
21 |
22 | return _isValueValid;
23 | }
24 |
25 | public CommandSettingsModel Settings { get; }
26 | }
27 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/ConsoleTraceListenerTestFixture.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using NUnit.Framework;
3 |
4 | namespace SqlPad.Oracle.Test
5 | {
6 | [SetUpFixture]
7 | public class ConsoleTraceListenerTestFixture
8 | {
9 | [OneTimeSetUp]
10 | public void SetUp()
11 | {
12 | Trace.Listeners.Add(new ConsoleTraceListener());
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/OracleSnippetProviderTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using NUnit.Framework;
5 | using Shouldly;
6 | using SqlPad.Test;
7 |
8 | namespace SqlPad.Oracle.Test
9 | {
10 | [TestFixture]
11 | public class OracleSnippetProviderTest : TemporaryDirectoryTestFixture
12 | {
13 | private static readonly OracleSnippetProvider SnippetProvider = new OracleSnippetProvider();
14 |
15 | [SetUp]
16 | public void SetUpSnippets()
17 | {
18 | ConfigurationProvider.SetSnippetsFolder(TempDirectoryName);
19 | ConfigurationProvider.SetCodeGenerationItemFolder(TempDirectoryName);
20 |
21 | var sourceDirectoryName = Path.Combine(Path.GetDirectoryName(new Uri(GetType().Assembly.CodeBase).LocalPath), "TestFiles");
22 |
23 | const string fileNameTestSnippet = "TestSnippet.xml";
24 | const string fileNameSelectSnippet = "SnippetSelect.xml";
25 | File.Copy(Path.Combine(sourceDirectoryName, fileNameTestSnippet), Path.Combine(TempDirectoryName, fileNameTestSnippet), true);
26 | File.Copy(Path.Combine(sourceDirectoryName, fileNameSelectSnippet), Path.Combine(TempDirectoryName, fileNameSelectSnippet), true);
27 | }
28 |
29 | [Test]
30 | public void TestSnippetSuggestionWithinStatementWhileTyping()
31 | {
32 | const string statementText = "SELECT DUMMY FROM\r\nD\r\nDUAL";
33 | var snippets = SnippetProvider.GetSnippets(statementText, 21, TestFixture.DatabaseModel).ToArray();
34 | snippets.Length.ShouldBe(0);
35 | }
36 |
37 | [Test]
38 | public void TestSnippetSuggestionAfterSemicolon()
39 | {
40 | const string statementText = ";SEL";
41 | var snippets = SnippetProvider.GetSnippets(statementText, 4, TestFixture.DatabaseModel).ToArray();
42 | snippets.Length.ShouldBe(1);
43 | }
44 |
45 | [Test]
46 | public void TestSnippetSuggestionAfterCommonTableExpression()
47 | {
48 | const string statementText = "WITH cte AS (SELECT * FROM DUAL) se";
49 | var snippets = SnippetProvider.GetSnippets(statementText, 35, TestFixture.DatabaseModel).ToArray();
50 | snippets.Length.ShouldBe(1);
51 | }
52 |
53 | [Test]
54 | public void TestSnippetWithoutParameterAndAllowedTerminals()
55 | {
56 | var snippets = SnippetProvider.GetSnippets("TES", 3, TestFixture.DatabaseModel).ToArray();
57 | snippets.Length.ShouldBe(1);
58 | snippets[0].Name.ShouldBe("Test");
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/OracleTestInfrastructureFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 |
3 | namespace SqlPad.Oracle.Test
4 | {
5 | public class OracleTestInfrastructureFactory : OracleInfrastructureFactory, IInfrastructureFactory
6 | {
7 | public new IDatabaseModel CreateDatabaseModel(ConnectionStringSettings connectionString, string identifier)
8 | {
9 | return OracleTestDatabaseModel.Instance;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/OracleTestObjectScriptExtractor.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DatabaseConnection;
4 | using SqlPad.Oracle.DataDictionary;
5 |
6 | namespace SqlPad.Oracle.Test
7 | {
8 | public class OracleTestObjectScriptExtractor : IOracleObjectScriptExtractor
9 | {
10 | internal const string SelectionTableCreateScript =
11 | @"CREATE TABLE ""HUSQVIK"".""SELECTION""
12 | (""SELECTION_ID"" NUMBER,
13 | ""CURRENTSTARTED"" NUMBER,
14 | ""CURRENTCOMPLETES"" NUMBER,
15 | ""STATUS"" NUMBER,
16 | ""RESPONDENTBUCKET_ID"" NUMBER,
17 | ""PROJECT_ID"" NUMBER,
18 | ""NAME"" VARCHAR2(100)
19 | ) SEGMENT CREATION IMMEDIATE
20 | PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
21 | NOCOMPRESS LOGGING
22 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
23 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
24 | BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
25 | TABLESPACE ""TBS_HQ_PDB""";
26 |
27 | internal const string TablespaceCreateScript =
28 | @"CREATE BIGFILE TABLESPACE ""TBS_HQ_PDB"" DATAFILE
29 | 'E:\ORACLE\ORADATA\HQ12C\HQ_PDB\TBS_HQ_PDB.DBF' SIZE 4294967296
30 | AUTOEXTEND ON NEXT 536870912 MAXSIZE 33554431M
31 | LOGGING ONLINE PERMANENT BLOCKSIZE 8192
32 | EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT
33 | NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO
34 | ALTER DATABASE DATAFILE
35 | 'E:\ORACLE\ORADATA\HQ12C\HQ_PDB\TBS_HQ_PDB.DBF' RESIZE 15032385536";
36 |
37 | public Task ExtractSchemaObjectScriptAsync(OracleObject schemaObject, CancellationToken cancellationToken)
38 | {
39 | return Task.FromResult(SelectionTableCreateScript);
40 | }
41 |
42 | public Task ExtractNonSchemaObjectScriptAsync(string objectName, string objectType, CancellationToken cancellationToken)
43 | {
44 | return Task.FromResult(TablespaceCreateScript);
45 | }
46 |
47 | public Task ExtractViewTextAsync(OracleObjectIdentifier viewIdentifier, CancellationToken cancellationToken)
48 | {
49 | return Task.FromResult("SELECT dummy FROM dual");
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("SqlPad.Oracle.Test")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("SqlPad.Oracle.Test")]
12 | [assembly: AssemblyCopyright("Copyright © 2016")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("b174dac5-9bec-4767-a27e-3765e0059c6c")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/StatementGrammarNodeTest.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using NUnit.Framework;
3 | using Shouldly;
4 | using NonTerminals = SqlPad.Oracle.OracleGrammarDescription.NonTerminals;
5 | using Terminals = SqlPad.Oracle.OracleGrammarDescription.Terminals;
6 |
7 | namespace SqlPad.Oracle.Test
8 | {
9 | [TestFixture]
10 | public class StatementGrammarNodeTest
11 | {
12 | private StatementGrammarNode _rootNode;
13 |
14 | [SetUp]
15 | public void SetUp()
16 | {
17 | const string sqlText = "WITH XXX AS (SELECT 3 COL FROM DUAL CTE_OUTER_ALIAS_1) SELECT VP1 COL1, (SELECT 1 FROM XXX SC_ALIAS_1) SCALARSUBQUERY FROM (WITH YYY AS (SELECT 1 FROM SYS.DUAL CTE_INNER_ALIAS_1), ZZZ AS (SELECT 2 FROM DUAL CTE_INNER_ALIAS_2), FFF AS (SELECT 4 FROM XXX CTE_INNER_ALIAS_3) SELECT COL + 1 VP1 FROM (SELECT COL FROM XXX TABLE_ALIAS_1, DUAL TABLE_ALIAS_2) TABLE_ALIAS_3) SUBQUERY";
18 | var result = OracleSqlParser.Instance.Parse(sqlText);
19 |
20 | result.Count.ShouldBe(1);
21 |
22 | var oracleStatement = result.Single();
23 | oracleStatement.ParseStatus.ShouldBe(ParseStatus.Success);
24 |
25 | _rootNode = oracleStatement.RootNode;
26 | }
27 |
28 | [Test]
29 | public void TestGetPathFilterDescendants()
30 | {
31 | var rootNestedQuery = _rootNode[0, 0, 0];
32 | var commonTableExpressions = rootNestedQuery.GetPathFilterDescendants(n => n.Id != NonTerminals.NestedQuery, NonTerminals.CommonTableExpression).ToArray();
33 | commonTableExpressions.Length.ShouldBe(1);
34 |
35 | commonTableExpressions = _rootNode.GetDescendants(NonTerminals.CommonTableExpression).ToArray();
36 | commonTableExpressions.Length.ShouldBe(4);
37 | }
38 |
39 | [Test]
40 | public void TestStatementCollectionGetNodeAtPositionAtSemicolonBetweenStatements()
41 | {
42 | var statements = OracleSqlParser.Instance.Parse("SELECT * FROM DUAL;SELECT * FROM DUAL");
43 | var node = statements.GetNodeAtPosition(18);
44 | node.Id.ShouldBe(Terminals.ObjectIdentifier);
45 |
46 | node = statements.GetNodeAtPosition(19);
47 | node.Id.ShouldBe(Terminals.Select);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/TestFiles/TestSnippet.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/SqlPad.Oracle.Test/TestFixture.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using SqlPad.Oracle.DatabaseConnection;
4 |
5 | namespace SqlPad.Oracle.Test
6 | {
7 | public class TestFixture
8 | {
9 | public static readonly OracleDatabaseModelBase DatabaseModel = OracleTestDatabaseModel.Instance;
10 |
11 | public static SqlDocumentRepository CreateDocumentRepository()
12 | {
13 | return new SqlDocumentRepository(OracleSqlParser.Instance, new OracleStatementValidator(), DatabaseModel);
14 | }
15 | }
16 |
17 | public static class TestExtensions
18 | {
19 | public static StatementBase Validate(this StatementBase statement)
20 | {
21 | if (statement.RootNode == null || statement.RootNode.TerminalCount <= 1)
22 | return statement;
23 |
24 | var sortedTerminals = statement.AllTerminals.OrderBy(t => t.SourcePosition.IndexStart).ToArray();
25 | var terminal = sortedTerminals[0];
26 | var allTerminals = statement.AllTerminals.ToArray();
27 |
28 | for (var i = 1; i < sortedTerminals.Length; i++)
29 | {
30 | var followingTerminal = sortedTerminals[i];
31 | if (terminal.SourcePosition.IndexEnd >= followingTerminal.SourcePosition.IndexStart)
32 | throw new InvalidOperationException($"Terminals '{terminal.Id}' and '{followingTerminal.Id}' within the statement are overlapping. ");
33 |
34 | if (followingTerminal != allTerminals[i])
35 | throw new InvalidOperationException($"Terminals within the statement are in invalid order (index {i}). ");
36 |
37 | terminal = followingTerminal;
38 | }
39 |
40 | return statement;
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/CodeGenerationItems/CreateFunction.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | CREATE FUNCTION
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/CodeGenerationItems/CreatePackage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | CREATE PACKAGE
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/CodeGenerationItems/CreatePackageBody.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 | CREATE PACKAGE
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/CodeGenerationItems/CreateProcedure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | CREATE PROCEDURE
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/AddToGroupByCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using SqlPad.Commands;
4 | using NonTerminals = SqlPad.Oracle.OracleGrammarDescription.NonTerminals;
5 |
6 | namespace SqlPad.Oracle.Commands
7 | {
8 | internal class AddToGroupByCommand : AddExpressionToClauseCommandBase
9 | {
10 | public const string Title = "Add to GROUP BY clause";
11 |
12 | private AddToGroupByCommand(ActionExecutionContext executionContext)
13 | : base(executionContext)
14 | {
15 | }
16 |
17 | protected override TextSegment ResolveAddedTextSegment()
18 | {
19 | var groupByClause = CurrentQueryBlock.RootNode[NonTerminals.GroupByClause];
20 | if (groupByClause == null)
21 | {
22 | var targetNode =
23 | CurrentQueryBlock.RootNode[NonTerminals.HierarchicalQueryClause]
24 | ?? CurrentQueryBlock.RootNode[NonTerminals.WhereClause]
25 | ?? CurrentQueryBlock.FromClause;
26 |
27 | if (targetNode?.LastTerminalNode != null)
28 | {
29 | return
30 | new TextSegment
31 | {
32 | IndextStart = targetNode.LastTerminalNode.SourcePosition.IndexEnd + 1,
33 | Length = 0,
34 | Text = $" GROUP BY {ExpressionText}"
35 | };
36 | }
37 |
38 | return TextSegment.Empty;
39 | }
40 |
41 | var groupingExpressions =
42 | groupByClause.GetPathFilterDescendants(n => !n.Id.In(NonTerminals.GroupingSetsClause, NonTerminals.RollupCubeClause, NonTerminals.NestedQuery, NonTerminals.HavingClause), NonTerminals.GroupingClause)
43 | .Where(n => n.ChildNodes.Count > 0 && String.Equals(n.ChildNodes[0].Id, NonTerminals.Expression));
44 |
45 | StatementGrammarNode lastGroupingExpression = null;
46 | foreach (var groupingExpression in groupingExpressions)
47 | {
48 | if (TerminalCollectionEqual(groupingExpression.Terminals, SelectedTerminals))
49 | {
50 | return TextSegment.Empty;
51 | }
52 |
53 | lastGroupingExpression = groupingExpression;
54 | }
55 |
56 | var commaPrefix = lastGroupingExpression == null ? String.Empty : ", ";
57 | return
58 | new TextSegment
59 | {
60 | IndextStart = (lastGroupingExpression?.SourcePosition.IndexEnd ?? groupByClause.SourcePosition.IndexEnd) + 1,
61 | Length = 0,
62 | Text = $"{commaPrefix}{ExpressionText}"
63 | };
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/AddToOrderByCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using SqlPad.Commands;
4 |
5 | namespace SqlPad.Oracle.Commands
6 | {
7 | internal class AddToOrderByCommand : AddExpressionToClauseCommandBase
8 | {
9 | public const string Title = "Add to ORDER BY clause";
10 |
11 | private AddToOrderByCommand(ActionExecutionContext executionContext)
12 | : base(executionContext)
13 | {
14 | }
15 |
16 | protected override TextSegment ResolveAddedTextSegment()
17 | {
18 | var subqueryNode = CurrentQueryBlock.RootNode.GetAncestor(OracleGrammarDescription.NonTerminals.Subquery);
19 | var orderByClause = subqueryNode[OracleGrammarDescription.NonTerminals.OrderByClause];
20 | if (orderByClause == null)
21 | {
22 | var targetNode = subqueryNode[OracleGrammarDescription.NonTerminals.OptionalParenthesisEnclosedConcatenatedQueryBlock];
23 | return
24 | new TextSegment
25 | {
26 | IndextStart = targetNode.LastTerminalNode.SourcePosition.IndexEnd + 1,
27 | Length = 0,
28 | Text = $" ORDER BY {ExpressionText}"
29 | };
30 | }
31 |
32 | var orderExpressions =
33 | orderByClause.GetPathFilterDescendants(n => !n.Id.In(OracleGrammarDescription.NonTerminals.NestedQuery), OracleGrammarDescription.NonTerminals.OrderExpression)
34 | .Where(n => n.ChildNodes.Count > 0);
35 |
36 | StatementGrammarNode lastOrderExpression = null;
37 | foreach (var orderExpression in orderExpressions)
38 | {
39 | if (TerminalCollectionEqual(orderExpression.Terminals, SelectedTerminals))
40 | {
41 | return TextSegment.Empty;
42 | }
43 |
44 | lastOrderExpression = orderExpression;
45 | }
46 |
47 | var commaPrefix = lastOrderExpression == null ? String.Empty : ", ";
48 | return
49 | new TextSegment
50 | {
51 | IndextStart = (lastOrderExpression?.SourcePosition.IndexEnd ?? orderByClause.SourcePosition.IndexEnd) + 1,
52 | Length = 0,
53 | Text = $"{commaPrefix}{ExpressionText}"
54 | };
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/CleanRedundantSymbolCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using SqlPad.Commands;
5 | using Terminals = SqlPad.Oracle.OracleGrammarDescription.Terminals;
6 |
7 | namespace SqlPad.Oracle.Commands
8 | {
9 | internal class CleanRedundantSymbolCommand : OracleCommandBase
10 | {
11 | public const string Title = "Clean redundant symbols";
12 |
13 | private IReadOnlyCollection _terminalGroupsToRemove;
14 |
15 | private CleanRedundantSymbolCommand(ActionExecutionContext executionContext)
16 | : base(executionContext)
17 | {
18 | }
19 |
20 | protected override CommandCanExecuteResult CanExecute()
21 | {
22 | var prerequisitesMet =
23 | ExecutionContext.SelectionLength == 0 && CurrentNode != null &&
24 | SemanticModel.RedundantSymbolGroups.Any();
25 |
26 | if (!prerequisitesMet)
27 | {
28 | return false;
29 | }
30 |
31 | var terminalGroupsToRemove = (IEnumerable)SemanticModel.RedundantSymbolGroups;
32 |
33 | var doGlobalClean = CurrentNode.Id.In(Terminals.Select, Terminals.Update, Terminals.Insert, Terminals.Delete, Terminals.Merge);
34 | if (doGlobalClean)
35 | {
36 | if (CurrentQueryBlock != null)
37 | {
38 | terminalGroupsToRemove = terminalGroupsToRemove.Where(g => g.Any(n => n.HasAncestor(CurrentQueryBlock.RootNode) || (CurrentQueryBlock.OrderByClause != null && n.HasAncestor(CurrentQueryBlock.OrderByClause))));
39 | }
40 | }
41 | else
42 | {
43 | terminalGroupsToRemove = terminalGroupsToRemove.Where(g => g.Contains(CurrentNode));
44 | }
45 |
46 | _terminalGroupsToRemove = terminalGroupsToRemove.ToArray();
47 |
48 | return _terminalGroupsToRemove.Count > 0;
49 | }
50 |
51 | protected override void Execute()
52 | {
53 | var removedTerminals = _terminalGroupsToRemove.SelectMany(g => g);
54 | var removedSegments = removedTerminals
55 | .Select(n =>
56 | new TextSegment
57 | {
58 | IndextStart = n.SourcePosition.IndexStart,
59 | Length = n.SourcePosition.Length,
60 | Text = String.Empty
61 | });
62 |
63 | ExecutionContext.SegmentsToReplace.AddRange(removedSegments);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/ExpandViewCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using SqlPad.Commands;
5 | using SqlPad.Oracle.DataDictionary;
6 | using SqlPad.Oracle.SemanticModel;
7 |
8 | namespace SqlPad.Oracle.Commands
9 | {
10 | internal class ExpandViewCommand : OracleCommandBase
11 | {
12 | private OracleView _view;
13 | private OracleDataObjectReference _objectReference;
14 | public const string Title = "Expand";
15 |
16 | private ExpandViewCommand(ActionExecutionContext executionContext)
17 | : base(executionContext)
18 | {
19 | }
20 |
21 | protected override CommandCanExecuteResult CanExecute()
22 | {
23 | if (CurrentNode == null)
24 | {
25 | return false;
26 | }
27 |
28 | _objectReference = SemanticModel.GetReference(CurrentNode);
29 | _view = _objectReference?.SchemaObject.GetTargetSchemaObject() as OracleView;
30 | return _view != null;
31 | }
32 |
33 | protected override void Execute()
34 | {
35 | ExecuteAsync(CancellationToken.None).Wait();
36 | }
37 |
38 | protected override async Task ExecuteAsync(CancellationToken cancellationToken)
39 | {
40 | var viewText = await SemanticModel.DatabaseModel.ObjectScriptExtractor.ExtractViewTextAsync(_view.FullyQualifiedName, cancellationToken);
41 | if (String.IsNullOrEmpty(viewText))
42 | {
43 | return;
44 | }
45 |
46 | var segment =
47 | new TextSegment
48 | {
49 | IndextStart = _objectReference.RootNode.SourcePosition.IndexStart,
50 | Text = $"({viewText}) "
51 | };
52 |
53 | ExecutionContext.SegmentsToReplace.Add(segment);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/ExtractPackageInterfaceCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using SqlPad.Commands;
5 | using SqlPad.Oracle.SemanticModel;
6 | using NonTerminals = SqlPad.Oracle.OracleGrammarDescription.NonTerminals;
7 |
8 | namespace SqlPad.Oracle.Commands
9 | {
10 | internal class ExtractPackageInterfaceCommand : OracleCommandBase
11 | {
12 | private OraclePlSqlProgram _program;
13 | public const string Title = "Extract interface";
14 |
15 | private readonly OraclePlSqlStatementSemanticModel _plSqlModel;
16 |
17 | private ExtractPackageInterfaceCommand(ActionExecutionContext executionContext)
18 | : base(executionContext)
19 | {
20 | _plSqlModel = SemanticModel as OraclePlSqlStatementSemanticModel;
21 | }
22 |
23 | protected override CommandCanExecuteResult CanExecute()
24 | {
25 | if (CurrentNode == null || _plSqlModel == null)
26 | {
27 | return false;
28 | }
29 |
30 | _program = _plSqlModel.Programs.SingleOrDefault(p => p.RootNode.SourcePosition.Contains(CurrentNode.SourcePosition));
31 | if (_program == null)
32 | {
33 | return false;
34 | }
35 |
36 | return
37 | _program.Type == PlSqlProgramType.PackageProgram && String.Equals(_program.RootNode.Id, NonTerminals.CreatePackageBody) &&
38 | CurrentNode.HasAncestor(_program.RootNode[NonTerminals.SchemaObject]);
39 | }
40 |
41 | protected override void Execute()
42 | {
43 | var interfaceBuilder = new StringBuilder();
44 | interfaceBuilder.AppendLine();
45 | interfaceBuilder.AppendLine();
46 |
47 | var packageName = _program.ObjectIdentifier.ToFormattedString();
48 | interfaceBuilder.AppendLine($"CREATE OR REPLACE PACKAGE {packageName} AS");
49 |
50 | foreach (var subProgram in _program.SubPrograms)
51 | {
52 | var signatureNode = subProgram.RootNode[0];
53 | if (!signatureNode.Id.In(NonTerminals.ProcedureHeading, NonTerminals.FunctionHeading))
54 | continue;
55 |
56 | interfaceBuilder.AppendLine($"\t{signatureNode.GetText(_plSqlModel.StatementText)};");
57 | }
58 |
59 | interfaceBuilder.AppendLine($"END {packageName};");
60 |
61 | var segment =
62 | new TextSegment
63 | {
64 | IndextStart = _program.RootNode.SourcePosition.IndexEnd + 1,
65 | Text = interfaceBuilder.ToString()
66 | };
67 |
68 | ExecutionContext.SegmentsToReplace.Add(segment);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/GenerateCustomTypeCSharpWrapperClassCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using System.Windows;
5 | using SqlPad.Commands;
6 | using SqlPad.Oracle.DataDictionary;
7 | using SqlPad.Oracle.SemanticModel;
8 | using Terminals = SqlPad.Oracle.OracleGrammarDescription.Terminals;
9 |
10 | namespace SqlPad.Oracle.Commands
11 | {
12 | internal class GenerateCustomTypeCSharpWrapperClassCommand : OracleCommandBase
13 | {
14 | public const string Title = "Generate C# class";
15 |
16 | private OracleTypeBase _oracleObjectType;
17 |
18 | private GenerateCustomTypeCSharpWrapperClassCommand(ActionExecutionContext executionContext)
19 | : base(executionContext)
20 | {
21 | }
22 |
23 | protected override CommandCanExecuteResult CanExecute()
24 | {
25 | if (!String.Equals(CurrentNode?.Id, Terminals.Identifier))
26 | {
27 | return false;
28 | }
29 |
30 | var semanticModel = (OracleStatementSemanticModel)ExecutionContext.DocumentRepository.ValidationModels[CurrentNode.Statement].SemanticModel;
31 | _oracleObjectType = (OracleTypeBase)semanticModel.GetTypeReference(CurrentNode)?.SchemaObject.GetTargetSchemaObject();
32 |
33 | return _oracleObjectType != null && _oracleObjectType.FullyQualifiedName != OracleDataType.XmlType.FullyQualifiedName;
34 | }
35 |
36 | protected override void Execute()
37 | {
38 | var builder = new StringBuilder();
39 | using (var writer = new StringWriter(builder))
40 | {
41 | CustomTypeCSharpWrapperClassGenerator.Generate(_oracleObjectType, writer);
42 | }
43 |
44 | Clipboard.SetText(builder.ToString());
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/SplitStringCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using SqlPad.Commands;
4 | using Terminals = SqlPad.Oracle.OracleGrammarDescription.Terminals;
5 |
6 | namespace SqlPad.Oracle.Commands
7 | {
8 | internal class SplitStringCommand : OracleCommandBase
9 | {
10 | public const string Title = "Split string";
11 |
12 | private const char SingleQuoteCharacter = '\'';
13 |
14 | private int _trimIndex;
15 | private bool _isQuotedString;
16 | private int _positionInString;
17 |
18 | private string LiteralValue => CurrentNode.Token.Value;
19 |
20 | private SplitStringCommand(ActionExecutionContext executionContext)
21 | : base(executionContext)
22 | {
23 | }
24 |
25 | protected override CommandCanExecuteResult CanExecute()
26 | {
27 | var isAtStringLiteral = CurrentNode != null && String.Equals(CurrentNode.Id, Terminals.StringLiteral);
28 | if (!isAtStringLiteral)
29 | {
30 | return false;
31 | }
32 |
33 | _trimIndex = OracleExtensions.GetTrimIndex(LiteralValue, out _isQuotedString, out var quoteInitializer);
34 | var endOffset = _isQuotedString ? 1 : 0;
35 | _positionInString = ExecutionContext.CaretOffset - CurrentNode.SourcePosition.IndexStart;
36 |
37 | if (IsAfterOddApostrophe())
38 | {
39 | _positionInString++;
40 | }
41 |
42 | return _positionInString >= _trimIndex && _positionInString < LiteralValue.Length - endOffset;
43 | }
44 |
45 | private bool IsAfterOddApostrophe()
46 | {
47 | if (_isQuotedString || LiteralValue[_positionInString] != SingleQuoteCharacter)
48 | {
49 | return false;
50 | }
51 |
52 | return LiteralValue.Substring(0, _positionInString)
53 | .Reverse()
54 | .TakeWhile(c => c == SingleQuoteCharacter)
55 | .Count() % 2 == 1;
56 | }
57 |
58 | protected override void Execute()
59 | {
60 | var stringInitializer = _isQuotedString ? LiteralValue.Substring(0, _trimIndex) : "'";
61 | var stringFinalizer = _isQuotedString ? LiteralValue.Substring(LiteralValue.Length - 2, 2) : "'";
62 |
63 | var firstPart = LiteralValue.Substring(0, _positionInString);
64 | var secondPart = LiteralValue.Substring(_positionInString);
65 |
66 | ExecutionContext.SegmentsToReplace.Add(
67 | new TextSegment
68 | {
69 | IndextStart = CurrentNode.SourcePosition.IndexStart,
70 | Length = CurrentNode.SourcePosition.Length,
71 | Text = $"{firstPart}{stringFinalizer} || || {stringInitializer}{secondPart}"
72 | });
73 |
74 | ExecutionContext.CaretOffset = CurrentNode.SourcePosition.IndexStart + firstPart.Length + stringFinalizer.Length + 4;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/SqlTextBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace SqlPad.Oracle.Commands
4 | {
5 | public class SqlTextBuilder
6 | {
7 | private static readonly OracleConfigurationFormatterFormatOptions FormatOptions = OracleConfiguration.Configuration.Formatter.FormatOptions;
8 |
9 | private readonly StringBuilder _builder = new StringBuilder();
10 |
11 | public override string ToString()
12 | {
13 | return _builder.ToString();
14 | }
15 |
16 | public void AppendIdentifier(string value)
17 | {
18 | AppendFormat(value, FormatOptions.Identifier);
19 | }
20 |
21 | public void AppendAlias(string value)
22 | {
23 | AppendFormat(value, FormatOptions.Alias);
24 | }
25 |
26 | public void AppendKeyword(string value)
27 | {
28 | AppendFormat(value, FormatOptions.Keyword);
29 | }
30 |
31 | public void AppendReservedWord(string value)
32 | {
33 | AppendFormat(value, FormatOptions.ReservedWord);
34 | }
35 |
36 | public void AppendText(string value)
37 | {
38 | _builder.Append(value);
39 | }
40 |
41 | public void AppendLine()
42 | {
43 | _builder.AppendLine();
44 | }
45 |
46 | private void AppendFormat(string value, FormatOption formatOption)
47 | {
48 | var formattedValue = OracleStatementFormatter.FormatTerminalValue(value, formatOption);
49 | _builder.Append(formattedValue);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Commands/ToggleQuotedNotationCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using SqlPad.Commands;
5 | using Terminals = SqlPad.Oracle.OracleGrammarDescription.Terminals;
6 |
7 | namespace SqlPad.Oracle.Commands
8 | {
9 | internal class ToggleQuotedNotationCommand : OracleCommandBase
10 | {
11 | public const string Title = "Toggle quoted notation";
12 |
13 | private StatementGrammarNode _sourceNode;
14 |
15 | private ToggleQuotedNotationCommand(ActionExecutionContext executionContext)
16 | : base(executionContext)
17 | {
18 | }
19 |
20 | protected override CommandCanExecuteResult CanExecute()
21 | {
22 | if (CurrentNode == null || CurrentNode != CurrentNode.Statement.RootNode.FirstTerminalNode)
23 | {
24 | return false;
25 | }
26 |
27 | _sourceNode = CurrentQueryBlock != null && String.Equals(CurrentNode.Id, Terminals.Select)
28 | ? CurrentQueryBlock.RootNode
29 | : CurrentNode.Statement.RootNode;
30 |
31 | return GetReplacedSegments().Any();
32 | }
33 |
34 | protected override void Execute()
35 | {
36 | ExecutionContext.SegmentsToReplace.AddRange(GetReplacedSegments());
37 | }
38 |
39 | private IEnumerable GetReplacedSegments()
40 | {
41 | bool? enableQuotes = null;
42 | foreach (var identifier in _sourceNode.Terminals.Where(t => t.Id.IsIdentifierOrAlias() && t.Token.Value.ToQuotedIdentifier() != t.Token.Value.ToSimpleIdentifier() && !t.Token.Value.CollidesWithReservedWord()))
43 | {
44 | if (!enableQuotes.HasValue)
45 | {
46 | enableQuotes = !identifier.Token.Value.IsQuoted();
47 | }
48 |
49 | if ((enableQuotes.Value && identifier.Token.Value.IsQuoted()) ||
50 | !enableQuotes.Value && !identifier.Token.Value.IsQuoted())
51 | continue;
52 |
53 | var replacedLength = enableQuotes.Value ? 0 : 1;
54 | var newText = enableQuotes.Value ? "\"" : String.Empty;
55 |
56 | yield return new TextSegment
57 | {
58 | IndextStart = identifier.SourcePosition.IndexStart,
59 | Length = replacedLength,
60 | Text = newText
61 | };
62 |
63 | yield return new TextSegment
64 | {
65 | IndextStart = identifier.SourcePosition.IndexEnd + 1 - replacedLength,
66 | Length = replacedLength,
67 | Text = newText
68 | };
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/DataDictionary/OracleColumn.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace SqlPad.Oracle.DataDictionary
4 | {
5 | [DebuggerDisplay("OracleColumn (Name={Name}; Type={FullTypeName}; Nullable={Nullable})")]
6 | public class OracleColumn
7 | {
8 | private const string ColumnNameColumnValue = "\"COLUMN_VALUE\"";
9 |
10 | public OracleColumn(bool isPseudocolumn = false)
11 | {
12 | IsPseudocolumn = isPseudocolumn;
13 | }
14 |
15 | public OracleDataType DataType { get; set; }
16 |
17 | public string Name { get; set; }
18 |
19 | public string FullTypeName => OracleDataType.ResolveFullTypeName(DataType, CharacterSize);
20 |
21 | public int? CharacterSize { get; set; }
22 |
23 | public bool Nullable { get; set; }
24 |
25 | public bool Virtual { get; set; }
26 |
27 | public bool? UserGenerated { get; set; }
28 |
29 | public bool Hidden { get; set; }
30 |
31 | public string DefaultValue { get; set; }
32 |
33 | public bool IsPseudocolumn { get; private set; }
34 |
35 | public OracleColumn Clone()
36 | {
37 | return
38 | new OracleColumn
39 | {
40 | DataType = DataType,
41 | Name = Name,
42 | CharacterSize = CharacterSize,
43 | Nullable = Nullable,
44 | Hidden = Hidden
45 | };
46 | }
47 |
48 | public static OracleColumn BuildColumnValueColumn(OracleDataType columnType)
49 | {
50 | return
51 | new OracleColumn
52 | {
53 | Name = ColumnNameColumnValue,
54 | DataType = columnType,
55 | Nullable = true
56 | };
57 | }
58 | }
59 |
60 | public enum DataUnit
61 | {
62 | NotApplicable,
63 | Byte,
64 | Character
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/DataDictionary/OracleConstraint.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 |
4 | namespace SqlPad.Oracle.DataDictionary
5 | {
6 | public abstract class OracleConstraint : OracleObject
7 | {
8 | public abstract ConstraintType ConstraintType { get; }
9 |
10 | public OracleSchemaObject OwnerObject { get; set; }
11 |
12 | public IList Columns { get; set; }
13 |
14 | public bool IsEnabled { get; set; }
15 |
16 | public bool IsDeferrable { get; set; }
17 |
18 | public bool IsValidated { get; set; }
19 |
20 | public bool IsRelied { get; set; }
21 |
22 | public override string Type { get; } = OracleObjectType.Constraint;
23 | }
24 |
25 | [DebuggerDisplay("OraclePrimaryKeyConstraint (Name={FullyQualifiedName.Name}; IsEnabled={IsEnabled}; IsDeferrable={IsDeferrable}; IsValidated={IsValidated}; IsRelied={IsRelied})")]
26 | public class OraclePrimaryKeyConstraint : OracleUniqueConstraint
27 | {
28 | public override ConstraintType ConstraintType => ConstraintType.PrimaryKey;
29 | }
30 |
31 | [DebuggerDisplay("OracleUniqueConstraint (Name={FullyQualifiedName.Name}; IsEnabled={IsEnabled}; IsDeferrable={IsDeferrable}; IsValidated={IsValidated}; IsRelied={IsRelied})")]
32 | public class OracleUniqueConstraint : OracleConstraint
33 | {
34 | public override ConstraintType ConstraintType => ConstraintType.Unique;
35 | }
36 |
37 | [DebuggerDisplay("OracleCheckConstraint (Name={FullyQualifiedName.Name}; IsEnabled={IsEnabled}; IsDeferrable={IsDeferrable}; IsValidated={IsValidated}; IsRelied={IsRelied})")]
38 | public class OracleCheckConstraint : OracleConstraint
39 | {
40 | public override ConstraintType ConstraintType => ConstraintType.Check;
41 | }
42 |
43 | [DebuggerDisplay("OracleForeignKeyConstraint (Name={FullyQualifiedName.Name}; IsEnabled={IsEnabled}; IsDeferrable={IsDeferrable}; IsValidated={IsValidated}; IsRelied={IsRelied})")]
44 | public class OracleReferenceConstraint : OracleConstraint
45 | {
46 | public OracleSchemaObject TargetObject { get; set; }
47 |
48 | public OracleUniqueConstraint ReferenceConstraint { get; set; }
49 |
50 | public DeleteRule DeleteRule { get; set; }
51 |
52 | public override ConstraintType ConstraintType => ConstraintType.ForeignKey;
53 | }
54 |
55 | public enum ConstraintType
56 | {
57 | PrimaryKey,
58 | Unique,
59 | Check,
60 | ForeignKey,
61 | }
62 |
63 | public enum DeleteRule
64 | {
65 | None,
66 | SetNull,
67 | Cascade
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/DataDictionary/OracleDatabaseLink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace SqlPad.Oracle.DataDictionary
5 | {
6 | [DebuggerDisplay("OracleDatabaseLink (Name={FullyQualifiedName.Name}; Host={Host}; UserName={UserName}; Created={Created})")]
7 | public class OracleDatabaseLink : OracleObject
8 | {
9 | public string UserName { get; set; }
10 |
11 | public string Host { get; set; }
12 |
13 | public DateTime Created { get; set; }
14 |
15 | public override string Type { get; } = OracleObjectType.DatabaseLink;
16 | }
17 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/DataDictionary/OracleObjectFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SqlPad.Oracle.DataDictionary
4 | {
5 | internal static class OracleObjectFactory
6 | {
7 | public static OracleSchemaObject CreateSchemaObjectMetadata(string objectType, string owner, string name, bool isValid, DateTime created, DateTime lastDdl, bool isTemporary)
8 | {
9 | var schemaObject = CreateObjectMetadata(objectType);
10 | schemaObject.FullyQualifiedName = OracleObjectIdentifier.Create(owner, name);
11 | schemaObject.IsValid = isValid;
12 | schemaObject.Created = created;
13 | schemaObject.LastDdl = lastDdl;
14 | schemaObject.IsTemporary = isTemporary;
15 |
16 | return schemaObject;
17 | }
18 |
19 | public static OracleConstraint CreateConstraint(string constraintType, string owner, string name, bool isEnabled, bool isValidated, bool isDeferrable, bool isRelied)
20 | {
21 | var constraint = CreateConstraint(constraintType);
22 | constraint.FullyQualifiedName = OracleObjectIdentifier.Create(owner, name);
23 | constraint.IsEnabled = isEnabled;
24 | constraint.IsValidated = isValidated;
25 | constraint.IsDeferrable = isDeferrable;
26 | constraint.IsRelied = isRelied;
27 |
28 | return constraint;
29 | }
30 |
31 | private static OracleConstraint CreateConstraint(string constraintType)
32 | {
33 | switch (constraintType)
34 | {
35 | case "P":
36 | return new OraclePrimaryKeyConstraint();
37 | case "U":
38 | return new OracleUniqueConstraint();
39 | case "R":
40 | return new OracleReferenceConstraint();
41 | case "C":
42 | return new OracleCheckConstraint();
43 | default:
44 | throw new InvalidOperationException($"Constraint type '{constraintType}' not supported. ");
45 | }
46 | }
47 |
48 | private static OracleSchemaObject CreateObjectMetadata(string objectType)
49 | {
50 | switch (objectType)
51 | {
52 | case OracleObjectType.Table:
53 | return new OracleTable();
54 | case OracleObjectType.View:
55 | return new OracleView();
56 | case OracleObjectType.Synonym:
57 | return new OracleSynonym();
58 | case OracleObjectType.Function:
59 | return new OracleFunction();
60 | case OracleObjectType.Procedure:
61 | return new OracleProcedure();
62 | case OracleObjectType.Sequence:
63 | return new OracleSequence();
64 | case OracleObjectType.Package:
65 | return new OraclePackage();
66 | case OracleObjectType.Directory:
67 | return new OracleDirectory();
68 | default:
69 | throw new InvalidOperationException($"Object type '{objectType}' not supported. ");
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/DatabaseConnection/OracleConnectionAdapterBase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using SqlPad.Oracle.ExecutionPlan;
5 | using SqlPad.Oracle.DebugTrace;
6 |
7 | namespace SqlPad.Oracle.DatabaseConnection
8 | {
9 | public abstract class OracleConnectionAdapterBase : IConnectionAdapter
10 | {
11 | public abstract IDatabaseModel DatabaseModel { get; }
12 |
13 | public abstract IDebuggerSession DebuggerSession { get; }
14 |
15 | public virtual void Dispose() { }
16 |
17 | public abstract bool CanFetch(ResultInfo resultInfo);
18 |
19 | public abstract bool IsExecuting { get; }
20 |
21 | public abstract bool EnableDatabaseOutput { get; set; }
22 |
23 | public abstract string Identifier { get; set; }
24 |
25 | public abstract Task ExecuteStatementAsync(StatementBatchExecutionModel executionModel, CancellationToken cancellationToken);
26 |
27 | public abstract Task ExecuteChildStatementAsync(StatementExecutionModel executionModel, CancellationToken cancellationToken);
28 |
29 | public abstract Task RefreshResult(StatementExecutionResult result, CancellationToken cancellationToken);
30 |
31 | public abstract Task> GetExecutionStatisticsAsync(CancellationToken cancellationToken);
32 |
33 | public abstract Task> FetchRecordsAsync(ResultInfo resultInfo, int rowCount, CancellationToken cancellationToken);
34 |
35 | public abstract bool HasActiveTransaction { get; }
36 |
37 | public abstract string TransanctionIdentifier { get; }
38 |
39 | public abstract Task CommitTransaction();
40 |
41 | public abstract Task RollbackTransaction();
42 |
43 | public abstract Task ExplainPlanAsync(StatementExecutionModel executionModel, CancellationToken cancellationToken);
44 |
45 | public abstract Task GetCursorExecutionStatisticsAsync(CancellationToken cancellationToken);
46 |
47 | public abstract Task ActivateTraceEvents(IEnumerable traceEvents, string traceIdentifier, CancellationToken cancellationToken);
48 |
49 | public abstract Task StopTraceEvents(CancellationToken cancellationToken);
50 |
51 | public abstract string TraceFileName { get; }
52 |
53 | public abstract SessionIdentifier? SessionIdentifier { get; }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/DatabaseConnection/OracleObjectScriptExtractor.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DataDictionary;
4 | using SqlPad.Oracle.ModelDataProviders;
5 |
6 | namespace SqlPad.Oracle.DatabaseConnection
7 | {
8 | public interface IOracleObjectScriptExtractor
9 | {
10 | Task ExtractSchemaObjectScriptAsync(OracleObject schemaObject, CancellationToken cancellationToken);
11 |
12 | Task ExtractNonSchemaObjectScriptAsync(string objectName, string objectType, CancellationToken cancellationToken);
13 |
14 | Task ExtractViewTextAsync(OracleObjectIdentifier viewIdentifier, CancellationToken cancellationToken);
15 | }
16 |
17 | public class OracleObjectScriptExtractor : IOracleObjectScriptExtractor
18 | {
19 | private readonly OracleDatabaseModelBase _databaseModel;
20 |
21 | public OracleObjectScriptExtractor(OracleDatabaseModelBase databaseModel)
22 | {
23 | _databaseModel = databaseModel;
24 | }
25 |
26 | public async Task ExtractSchemaObjectScriptAsync(OracleObject schemaObject, CancellationToken cancellationToken)
27 | {
28 | var scriptDataProvider = new ObjectScriptDataProvider(schemaObject);
29 | await UpdateDataModel(cancellationToken, scriptDataProvider);
30 | return scriptDataProvider.ScriptText;
31 | }
32 |
33 | public async Task ExtractNonSchemaObjectScriptAsync(string objectName, string objectType, CancellationToken cancellationToken)
34 | {
35 | var scriptDataProvider = new ObjectScriptDataProvider(objectName, objectType);
36 | await UpdateDataModel(cancellationToken, scriptDataProvider);
37 | return scriptDataProvider.ScriptText;
38 | }
39 |
40 | public async Task ExtractViewTextAsync(OracleObjectIdentifier viewIdentifier, CancellationToken cancellationToken)
41 | {
42 | var dataModel = new ViewDetailModel();
43 | var viewDetailsDataProvider = new ViewDetailDataProvider(dataModel, viewIdentifier, _databaseModel.Version);
44 | await UpdateDataModel(cancellationToken, viewDetailsDataProvider);
45 | return dataModel.Text;
46 | }
47 |
48 | private async Task UpdateDataModel(CancellationToken cancellationToken, IModelDataProvider scriptDataProvider)
49 | {
50 | var connectionString = OracleConnectionStringRepository.GetBackgroundConnectionString(_databaseModel.ConnectionString.ConnectionString);
51 | await OracleDatabaseModel.UpdateModelAsync(connectionString, _databaseModel.CurrentSchema, false, cancellationToken, scriptDataProvider);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/DebugTrace/OracleTraceIdentifier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SqlPad.Oracle.DebugTrace
4 | {
5 | public static class OracleTraceIdentifier
6 | {
7 | public static string Normalize(string traceIdentifier)
8 | {
9 | return String.IsNullOrEmpty(traceIdentifier) ? "''''" : $"\"{traceIdentifier.Replace('"', '_').Replace("'", "''")}\"";
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/Documentation.Extensions.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Serialization;
2 |
3 | namespace SqlPad.Oracle
4 | {
5 | public partial class DocumentationPackageSubProgram
6 | {
7 | [XmlIgnore]
8 | public DocumentationPackage PackageDocumentation { get; internal set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ExecutionPlan/ExecutionStatisticsPlanItemCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace SqlPad.Oracle.ExecutionPlan
5 | {
6 | public class ExecutionStatisticsPlanItemCollection : ExecutionPlanItemCollectionBase
7 | {
8 | public string PlanText { get; set; }
9 | }
10 |
11 | [DebuggerDisplay("ExecutionStatisticsPlanItem (Id={Id}; Operation={Operation}; Depth={Depth}; IsLeaf={IsLeaf}; ExecutionOrder={ExecutionOrder})")]
12 | public class ExecutionStatisticsPlanItem : ExecutionPlanItem
13 | {
14 | public DateTime Timestamp { get; set; }
15 |
16 | public int Executions { get; set; }
17 |
18 | public int? LastStarts { get; set; }
19 |
20 | public int? TotalStarts { get; set; }
21 |
22 | public long? LastOutputRows { get; set; }
23 |
24 | public long? TotalOutputRows { get; set; }
25 |
26 | public long? LastConsistentReadBufferGets { get; set; }
27 |
28 | public long? TotalConsistentReadBufferGets { get; set; }
29 |
30 | public long? LastCurrentReadBufferGets { get; set; }
31 |
32 | public long? TotalCurrentReadBufferGets { get; set; }
33 |
34 | public long? LastDiskReads { get; set; }
35 |
36 | public long? TotalDiskReads { get; set; }
37 |
38 | public long? LastDiskWrites { get; set; }
39 |
40 | public long? TotalDiskWrites { get; set; }
41 |
42 | public TimeSpan? LastElapsedTime { get; set; }
43 |
44 | public TimeSpan? TotalElapsedTime { get; set; }
45 |
46 | public string WorkAreaSizingPolicy { get; set; }
47 |
48 | public long? EstimatedOptimalSizeBytes { get; set; }
49 |
50 | public long? EstimatedOnePassSizeBytes { get; set; }
51 |
52 | public long? LastMemoryUsedBytes { get; set; }
53 |
54 | public string LastExecutionMethod { get; set; }
55 |
56 | public int? LastParallelDegree { get; set; }
57 |
58 | public int? TotalWorkAreaExecutions { get; set; }
59 |
60 | public int? OptimalWorkAreaExecutions { get; set; }
61 |
62 | public int? OnePassWorkAreaExecutions { get; set; }
63 |
64 | public int? MultiPassWorkAreaExecutions { get; set; }
65 |
66 | public TimeSpan? ActiveWorkAreaTime { get; set; }
67 |
68 | public long? MaxTemporarySizeBytes { get; set; }
69 |
70 | public long? LastTemporarySizeBytes { get; set; }
71 | }
72 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/GenerateXsdClasses.cmd:
--------------------------------------------------------------------------------
1 | xsd OracleSqlGrammar.xsd /c /n:SqlPad.Oracle
2 | xsd OracleConfiguration.xsd /c /n:SqlPad.Oracle
3 | xsd Documentation.xsd /c /n:SqlPad.Oracle
--------------------------------------------------------------------------------
/SqlPad.Oracle/ModelDataProviders/IModelDataProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | #if ORACLE_MANAGED_DATA_ACCESS_CLIENT
5 | using Oracle.ManagedDataAccess.Client;
6 | #else
7 | using Oracle.DataAccess.Client;
8 | #endif
9 |
10 | namespace SqlPad.Oracle.ModelDataProviders
11 | {
12 | internal interface IModelDataProvider
13 | {
14 | void InitializeCommand(OracleCommand command);
15 |
16 | Task MapReaderData(OracleDataReader reader, CancellationToken cancellationToken);
17 |
18 | void MapScalarValue(object value);
19 |
20 | bool HasScalarResult { get; }
21 |
22 | bool IsValid { get; }
23 | }
24 |
25 | internal abstract class ModelDataProvider : IModelDataProvider
26 | {
27 | protected TModel DataModel { get; private set; }
28 |
29 | protected ModelDataProvider(TModel dataModel)
30 | {
31 | DataModel = dataModel;
32 | }
33 |
34 | public abstract void InitializeCommand(OracleCommand command);
35 |
36 | public virtual Task MapReaderData(OracleDataReader reader, CancellationToken cancellationToken)
37 | {
38 | throw new NotSupportedException("Override this method if you want to map data from the reader. ");
39 | }
40 |
41 | public virtual bool HasScalarResult => false;
42 |
43 | public virtual bool IsValid => true;
44 |
45 | public virtual void MapScalarValue(object value)
46 | {
47 | throw new NotSupportedException("Override this method to get scalar value from a query. ");
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ModelDataProviders/UserDataProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using SqlPad.Oracle.DatabaseConnection;
5 | using SqlPad.Oracle.ToolTips;
6 | #if ORACLE_MANAGED_DATA_ACCESS_CLIENT
7 | using Oracle.ManagedDataAccess.Client;
8 | #else
9 | using Oracle.DataAccess.Client;
10 | #endif
11 |
12 | namespace SqlPad.Oracle.ModelDataProviders
13 | {
14 | internal class UserDataProvider : ModelDataProvider
15 | {
16 | public UserDataProvider(OracleSchemaModel dataModel)
17 | : base(dataModel)
18 | {
19 | }
20 |
21 | public override void InitializeCommand(OracleCommand command)
22 | {
23 | command.CommandText = OracleDatabaseCommands.SelectUserAdditionalData;
24 | command.AddSimpleParameter("USERNAME", DataModel.Schema.Name.Trim('"'));
25 | }
26 |
27 | public override async Task MapReaderData(OracleDataReader reader, CancellationToken cancellationToken)
28 | {
29 | if (!await reader.ReadAsynchronous(cancellationToken))
30 | {
31 | return;
32 | }
33 |
34 | DataModel.AccountStatus = (string)reader["ACCOUNT_STATUS"];
35 | DataModel.LockDate = OracleReaderValueConvert.ToDateTime(reader["LOCK_DATE"]);
36 | DataModel.ExpiryDate = OracleReaderValueConvert.ToDateTime(reader["EXPIRY_DATE"]);
37 | DataModel.DefaultTablespace = (string)reader["DEFAULT_TABLESPACE"];
38 | DataModel.TemporaryTablespace = (string)reader["TEMPORARY_TABLESPACE"];
39 | DataModel.Profile = (string)reader["PROFILE"];
40 | DataModel.EditionsEnabled = String.Equals((string)reader["EDITIONS_ENABLED"], "Y");
41 | DataModel.AuthenticationType = (string)reader["AUTHENTICATION_TYPE"];
42 | DataModel.LastLogin = OracleReaderValueConvert.ToDateTime(reader["LAST_LOGIN"]);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleBindVariable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using TerminalValues = SqlPad.Oracle.OracleGrammarDescription.TerminalValues;
5 |
6 | namespace SqlPad.Oracle
7 | {
8 | public static class OracleBindVariable
9 | {
10 | public const string DataTypeUnicodeClob = "NCLOB";
11 | public const string DataTypeRefCursor = "REF CURSOR";
12 |
13 | public static readonly ReadOnlyDictionary DataTypes =
14 | new ReadOnlyDictionary(
15 | new Dictionary
16 | {
17 | { TerminalValues.Char, new BindVariableType(TerminalValues.Char, typeof(string), false) },
18 | { TerminalValues.Clob, new BindVariableType(TerminalValues.Clob, typeof(string), true) },
19 | { TerminalValues.Date, new BindVariableType(TerminalValues.Date, typeof(DateTime), false) },
20 | { TerminalValues.Timestamp, new BindVariableType(TerminalValues.Timestamp, typeof(DateTime), false) },
21 | { TerminalValues.NChar, new BindVariableType(TerminalValues.NChar, typeof(string), false) },
22 | { DataTypeUnicodeClob, new BindVariableType(DataTypeUnicodeClob, typeof(string), true) },
23 | { TerminalValues.Number, new BindVariableType(TerminalValues.Number, typeof(string), false) },
24 | { TerminalValues.NVarchar2, new BindVariableType(TerminalValues.NVarchar2, typeof(string), false) },
25 | { TerminalValues.Varchar2, new BindVariableType(TerminalValues.Varchar2, typeof(string), false) },
26 | { DataTypeRefCursor, new BindVariableType(DataTypeRefCursor, typeof(string), false) },
27 | { TerminalValues.Raw, new BindVariableType(TerminalValues.Raw, typeof(string), true) },
28 | { TerminalValues.Blob, new BindVariableType(TerminalValues.Blob, typeof(string), true) }
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleCommandSettingsProviderFactory.cs:
--------------------------------------------------------------------------------
1 | using SqlPad.Commands;
2 |
3 | namespace SqlPad.Oracle
4 | {
5 | public class OracleCommandSettingsProviderFactory : ICommandSettingsProviderFactory
6 | {
7 | public ICommandSettingsProvider CreateCommandSettingsProvider(CommandSettingsModel settings)
8 | {
9 | return new EditDialog(settings);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleConfiguration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ALTER SESSION SET optimizer_dynamic_sampling = 0 plsql_debug = true;
5 |
6 | BEGIN
7 | utl_http.set_body_charset('UTF8');
8 | utl_http.set_wallet(path => 'file:C:/oracle/wallet');
9 | END;
10 |
11 | C:\Oracle\product\12.1.0\dbhome_1\BIN\tkprof.exe
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleDataExportConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using TerminalValues = SqlPad.Oracle.OracleGrammarDescription.TerminalValues;
4 |
5 | namespace SqlPad.Oracle
6 | {
7 | public class OracleDataExportConverter : IDataExportConverter
8 | {
9 | public string ToSqlValue(object value)
10 | {
11 | var stringValue = value.ToString();
12 | if (String.IsNullOrEmpty(stringValue))
13 | {
14 | return TerminalValues.Null;
15 | }
16 |
17 | var vendorValue = value as IValue;
18 | return vendorValue != null
19 | ? vendorValue.ToSqlLiteral()
20 | : value is Int16 || value is Int32 || value is Int64
21 | ? stringValue
22 | : $"'{stringValue.Replace("'", "''")}'";
23 | }
24 |
25 | public string ToColumnName(string columnHeader)
26 | {
27 | if (columnHeader.Length > 30)
28 | {
29 | columnHeader = columnHeader.Substring(0, 30);
30 | }
31 |
32 | return
33 | columnHeader.RequiresQuotes()
34 | ? $"\"{columnHeader.Replace('"', ' ')}\""
35 | : columnHeader;
36 | }
37 |
38 | public string ToXml(object value)
39 | {
40 | var vendorValue = value as IValue;
41 | return vendorValue != null
42 | ? vendorValue.ToXml()
43 | : value.ToString().ToXmlCompliant();
44 | }
45 |
46 | public string ToJson(object value)
47 | {
48 | var stringValue = value.ToString();
49 | var vendorValue = value as IValue;
50 | return vendorValue != null
51 | ? vendorValue.ToJson()
52 | : value is Int16 || value is Int32 || value is Int64
53 | ? stringValue
54 | : $"\"{stringValue.Replace("\"", "\\\"")}\"";
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleIdentifierValidationRule.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Controls;
4 |
5 | namespace SqlPad.Oracle
6 | {
7 | public class OracleIdentifierValidationRule : ValidationRule
8 | {
9 | public override ValidationResult Validate(object value, CultureInfo cultureInfo)
10 | {
11 | var identifier = (string)value;
12 | return new ValidationResult(AllowEmpty && String.IsNullOrEmpty(identifier) || OracleSqlParser.IsValidIdentifier(identifier), "Identifier contains characters that are not allowed, starts with a number, has more than 30 characters or matches a reserved word. ");
13 | }
14 |
15 | public bool AllowEmpty { get; set; }
16 | }
17 |
18 | public class OracleBindVariableIdentifierValidationRule : ValidationRule
19 | {
20 | private readonly Version _databaseVersion;
21 |
22 | public OracleBindVariableIdentifierValidationRule(Version databaseVersion)
23 | {
24 | _databaseVersion = databaseVersion;
25 | }
26 |
27 | public override ValidationResult Validate(object value, CultureInfo cultureInfo)
28 | {
29 | return new ValidationResult(OracleStatementValidator.IsValidBindVariableIdentifier((string)value, _databaseVersion), "Bind variable identifier contains characters that are not allowed, has more than 30 characters, matches a reserved word or is a number value not between 0 and 65535. ");
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleSqlGrammar.Extension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text.RegularExpressions;
4 |
5 | namespace SqlPad.Oracle
6 | {
7 | [DebuggerDisplay("SqlGrammarStartSymbol (Id={" + nameof(Id) + "})")]
8 | public partial class SqlGrammarStartSymbol
9 | {
10 |
11 | }
12 |
13 | [DebuggerDisplay("SqlGrammarRuleSequence (Elements={Items.Length}, Comment={Comment})")]
14 | public partial class SqlGrammarRuleSequence
15 | {
16 | }
17 |
18 | [DebuggerDisplay("SqlGrammarTerminal (Id={Id}, Value={Value}, RegexValue={RegexValue})")]
19 | public partial class SqlGrammarTerminal
20 | {
21 | internal void Initialize()
22 | {
23 | if (!String.IsNullOrEmpty(RegexValue))
24 | {
25 | RegexMatcher = new Regex(RegexValue, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
26 | }
27 | }
28 |
29 | internal Regex RegexMatcher { get; private set; }
30 |
31 | internal bool IsFixed => RegexMatcher == null;
32 | }
33 |
34 | [DebuggerDisplay("SqlGrammarRuleSequenceTerminal (Id={Id}, IsOptional={IsOptional})")]
35 | public partial class SqlGrammarRuleSequenceTerminal : ISqlGrammarRuleSequenceItem
36 | {
37 | public bool IsRequired => !isOptionalFieldSpecified || (isOptionalFieldSpecified && !IsOptional);
38 |
39 | public NodeType Type => NodeType.Terminal;
40 |
41 | public SqlGrammarRuleSequence ParentSequence { get; set; }
42 |
43 | public int SequenceIndex { get; set; }
44 |
45 | public SqlGrammarTerminal Terminal;
46 | }
47 |
48 | [DebuggerDisplay("SqlGrammarRuleSequenceNonTerminal (Id={Id}, IsOptional={IsOptional})")]
49 | public partial class SqlGrammarRuleSequenceNonTerminal : ISqlGrammarRuleSequenceItem
50 | {
51 | public bool IsRequired => !isOptionalFieldSpecified || (isOptionalFieldSpecified && !IsOptional);
52 |
53 | public NodeType Type => NodeType.NonTerminal;
54 |
55 | public SqlGrammarRuleSequence ParentSequence { get; set; }
56 |
57 | public int SequenceIndex { get; set; }
58 |
59 | public SqlGrammarRule TargetRule;
60 | }
61 |
62 | public interface ISqlGrammarRuleSequenceItem
63 | {
64 | NodeType Type { get; }
65 |
66 | string Id { get; }
67 |
68 | bool IsRequired { get; }
69 |
70 | SqlGrammarRuleSequence ParentSequence { get; }
71 |
72 | int SequenceIndex { get; }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/OracleToken.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace SqlPad.Oracle
4 | {
5 | [DebuggerDisplay("OracleToken (Value={Value}, Index={Index})")]
6 | public struct OracleToken : IToken
7 | {
8 | public static OracleToken Empty = new OracleToken();
9 | public readonly CommentType CommentType;
10 | public readonly int Index;
11 | public readonly string Value;
12 | public readonly string UpperInvariantValue;
13 |
14 | public OracleToken(string value, int index, CommentType commentType = CommentType.None)
15 | {
16 | UpperInvariantValue = value.ToUpperInvariant();
17 | Value = value;
18 | Index = index;
19 | CommentType = commentType;
20 | }
21 |
22 | string IToken.Value => Value;
23 |
24 | int IToken.Index => Index;
25 |
26 | CommentType IToken.CommentType => CommentType;
27 | }
28 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using System.Windows;
5 | using SqlPad;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("SQL Pad for Oracle")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("SqlPad.Oracle")]
15 | [assembly: AssemblyCopyright("Copyright © 2016")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | [assembly: InternalsVisibleTo("SqlPad.Oracle.Test")]
25 | [assembly: InternalsVisibleTo("SqlPad.Oracle.Database.Test")]
26 |
27 | // The following GUID is for the ID of the typelib if this project is exposed to COM
28 | [assembly: Guid("8d6c6950-3d58-4806-b550-3dcd66579ef4")]
29 |
30 | // Version information for an assembly consists of the following four values:
31 | //
32 | // Major Version
33 | // Minor Version
34 | // Build Number
35 | // Revision
36 | //
37 | // You can specify all the values or you can default the Build and Revision Numbers
38 | // by using the '*' as shown below:
39 | // [assembly: AssemblyVersion("1.0.*")]
40 | [assembly: AssemblyVersion("0.4.0.489")]
41 | [assembly: AssemblyFileVersion("0.4.0.489")]
42 | [assembly: AssemblyBuildInfo("d7ddc296", "2019-05-12 11:07:36")]
43 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
--------------------------------------------------------------------------------
/SqlPad.Oracle/Scripts/CreateExplainPlanTable.sql:
--------------------------------------------------------------------------------
1 | CREATE GLOBAL TEMPORARY TABLE EXPLAIN_PLAN
2 | (
3 | STATEMENT_ID VARCHAR2(30),
4 | PLAN_ID NUMBER,
5 | TIMESTAMP DATE,
6 | REMARKS VARCHAR2(4000),
7 | OPERATION VARCHAR2(30),
8 | OPTIONS VARCHAR2(255),
9 | OBJECT_NODE VARCHAR2(128),
10 | OBJECT_OWNER VARCHAR2(30),
11 | OBJECT_NAME VARCHAR2(30),
12 | OBJECT_ALIAS VARCHAR2(65),
13 | OBJECT_INSTANCE INTEGER,
14 | OBJECT_TYPE VARCHAR2(30),
15 | OPTIMIZER VARCHAR2(255),
16 | SEARCH_COLUMNS NUMBER,
17 | ID INTEGER,
18 | PARENT_ID INTEGER,
19 | DEPTH INTEGER,
20 | POSITION INTEGER,
21 | COST INTEGER,
22 | CARDINALITY INTEGER,
23 | BYTES INTEGER,
24 | OTHER_TAG VARCHAR2(255),
25 | PARTITION_START VARCHAR2(255),
26 | PARTITION_STOP VARCHAR2(255),
27 | PARTITION_ID INTEGER,
28 | OTHER LONG,
29 | DISTRIBUTION VARCHAR2(30),
30 | CPU_COST INTEGER,
31 | IO_COST INTEGER,
32 | TEMP_SPACE INTEGER,
33 | ACCESS_PREDICATES VARCHAR2(4000),
34 | FILTER_PREDICATES VARCHAR2(4000),
35 | PROJECTION VARCHAR2(4000),
36 | TIME INTEGER,
37 | QBLOCK_NAME VARCHAR2(30),
38 | OTHER_XML CLOB
39 | )
40 | ON COMMIT PRESERVE ROWS;
41 |
42 | CREATE OR REPLACE PUBLIC SYNONYM EXPLAIN_PLAN FOR EXPLAIN_PLAN;
43 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleColumnReference.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using SqlPad.Oracle.DataDictionary;
6 |
7 | namespace SqlPad.Oracle.SemanticModel
8 | {
9 | [DebuggerDisplay("OracleColumnReference (Owner={OwnerNode == null ? null : OwnerNode.Token.Value}; Object={ObjectNode == null ? null : ObjectNode.Token.Value}; Column={ColumnNode.Token.Value}; Placement={Placement}; HasExplicitDefinition={HasExplicitDefinition})")]
10 | public class OracleColumnReference : OracleReference
11 | {
12 | private StatementGrammarNode _columnNode;
13 | private string _normalizedName;
14 |
15 | public OracleColumnReference(OracleReferenceContainer referenceContainer)
16 | {
17 | ColumnNodeObjectReferences = new HashSet();
18 | ColumnNodeColumnReferences = new List();
19 | Container = referenceContainer;
20 | }
21 |
22 | public override string Name => _columnNode.Token.Value;
23 |
24 | public override string NormalizedName => _normalizedName;
25 |
26 | public bool ReferencesAllColumns => String.Equals(_columnNode.Token.Value, "*");
27 |
28 | public StatementGrammarNode OldOuterJoinOperatorNode { get; set; }
29 |
30 | public StatementGrammarNode ColumnNode
31 | {
32 | get { return _columnNode; }
33 | set
34 | {
35 | if (_columnNode == value)
36 | {
37 | return;
38 | }
39 |
40 | _columnNode = value;
41 | _normalizedName = _columnNode?.Token.Value.ToQuotedIdentifier();
42 | }
43 | }
44 |
45 | public ICollection ColumnNodeObjectReferences { get; }
46 |
47 | public ICollection ColumnNodeColumnReferences { get; set; }
48 |
49 | public OracleColumn ColumnDescription { get; set; }
50 |
51 | public bool IsCorrelated { get; set; }
52 |
53 | public OracleObjectWithColumnsReference ValidObjectReference
54 | {
55 | get
56 | {
57 | if (ColumnNodeObjectReferences.Count == 1)
58 | return ColumnNodeObjectReferences.First();
59 |
60 | return ObjectNodeObjectReferences.Count == 1
61 | ? ObjectNodeObjectReferences.First()
62 | : null;
63 | }
64 | }
65 |
66 | protected override IEnumerable GetAdditionalIdentifierTerminals()
67 | {
68 | if (_columnNode != null)
69 | {
70 | yield return _columnNode;
71 | }
72 | }
73 |
74 | public override void Accept(IOracleReferenceVisitor visitor)
75 | {
76 | visitor.VisitColumnReference(this);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleDataTypeReference.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using SqlPad.Oracle.DataDictionary;
5 |
6 | namespace SqlPad.Oracle.SemanticModel
7 | {
8 | [DebuggerDisplay("OracleDataTypeReference (Owner={OwnerNode == null ? null : OwnerNode.Token.Value}; Name={ObjectNode.Token.Value}; SchemaObject={SchemaObject})")]
9 | public class OracleDataTypeReference : OracleReference
10 | {
11 | public override string Name => throw new NotSupportedException();
12 |
13 | public OracleDataType ResolvedDataType { get; set; }
14 |
15 | public StatementGrammarNode PrecisionNode { get; set; }
16 |
17 | public StatementGrammarNode ScaleNode { get; set; }
18 |
19 | public StatementGrammarNode LengthNode { get; set; }
20 |
21 | public ICollection PlSqlTypes { get; } = new List();
22 |
23 | public override void Accept(IOracleReferenceVisitor visitor)
24 | {
25 | visitor.VisitDataTypeReference(this);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleInsertTarget.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace SqlPad.Oracle.SemanticModel
5 | {
6 | public class OracleInsertTarget : OracleReferenceContainer
7 | {
8 | public OracleInsertTarget(OracleStatementSemanticModel semanticModel) : base(semanticModel)
9 | {
10 | }
11 |
12 | public StatementGrammarNode RootNode { get; set; }
13 |
14 | public StatementGrammarNode TargetNode { get; set; }
15 |
16 | public StatementGrammarNode ColumnListNode { get; set; }
17 |
18 | public StatementGrammarNode ValueList { get; set; }
19 |
20 | public IReadOnlyList ValueExpressions { get; set; }
21 |
22 | public IReadOnlyDictionary Columns { get; set; }
23 |
24 | public OracleQueryBlock RowSource { get; set; }
25 |
26 | public OracleDataObjectReference DataObjectReference => ObjectReferences.Count == 1 ? ObjectReferences.First() : null;
27 | }
28 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleJoinDescription.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace SqlPad.Oracle.SemanticModel
4 | {
5 | public class OracleJoinDescription
6 | {
7 | public OracleDataObjectReference MasterObjectReference { get; set; }
8 |
9 | public StatementGrammarNode MasterPartitionClause { get; set; }
10 |
11 | public OracleDataObjectReference SlaveObjectReference { get; set; }
12 |
13 | public StatementGrammarNode SlavePartitionClause { get; set; }
14 |
15 | public ICollection Columns { get; set; }
16 |
17 | public JoinType Type { get; set; }
18 |
19 | public JoinDefinition Definition { get; set; }
20 | }
21 |
22 | public enum JoinType
23 | {
24 | Inner,
25 | Left,
26 | Right,
27 | Full
28 | }
29 |
30 | public enum JoinDefinition
31 | {
32 | Explicit,
33 | Natural
34 | }
35 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleLiteral.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Oracle.SemanticModel
2 | {
3 | public enum LiteralType
4 | {
5 | Unknown,
6 | Date,
7 | IntervalYearToMonth,
8 | IntervalDayToSecond,
9 | Timestamp,
10 | Number,
11 | SinglePrecision,
12 | DoublePrecision,
13 | Char
14 | }
15 |
16 | public struct OracleLiteral
17 | {
18 | public LiteralType Type;
19 |
20 | public StatementGrammarNode Terminal;
21 |
22 | public bool IsMultibyte
23 | {
24 | get
25 | {
26 | if (Terminal == null || Terminal.Id != OracleGrammarDescription.Terminals.StringLiteral)
27 | {
28 | return false;
29 | }
30 |
31 | return Terminal.Token.Value[0] == 'n' || Terminal.Token.Value[0] == 'N';
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleProgramReference.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using SqlPad.Oracle.DataDictionary;
5 |
6 | namespace SqlPad.Oracle.SemanticModel
7 | {
8 | [DebuggerDisplay("OracleProgramReference (Owner={OwnerNode == null ? null : OwnerNode.Token.Value}; Object={ObjectNode == null ? null : ObjectNode.Token.Value}; Program={ProgramIdentifierNode.Token.Value}; Metadata={Metadata})")]
9 | public class OracleProgramReference : OracleProgramReferenceBase
10 | {
11 | public override string Name => ProgramIdentifierNode.Token.Value;
12 |
13 | public StatementGrammarNode ProgramIdentifierNode { get; set; }
14 |
15 | public StatementGrammarNode AnalyticClauseNode { get; set; }
16 |
17 | public override OracleProgramMetadata Metadata { get; set; }
18 |
19 | protected override IEnumerable GetAdditionalIdentifierTerminals()
20 | {
21 | if (ProgramIdentifierNode != null)
22 | {
23 | yield return ProgramIdentifierNode;
24 | }
25 | }
26 |
27 | public override void Accept(IOracleReferenceVisitor visitor)
28 | {
29 | visitor.VisitProgramReference(this);
30 | }
31 | }
32 |
33 | [DebuggerDisplay("OracleTypeReference (Owner={OwnerNode == null ? null : OwnerNode.Token.Value}; Type={ObjectNode.Token.Value}; Metadata={Metadata})")]
34 | public class OracleTypeReference : OracleProgramReferenceBase
35 | {
36 | public override string Name => ObjectNode.Token.Value;
37 |
38 | public override OracleProgramMetadata Metadata
39 | {
40 | get { return ((OracleTypeBase)SchemaObject.GetTargetSchemaObject()).GetConstructorMetadata(); }
41 | set { throw new NotSupportedException("Metadata cannot be set. It is inferred from type attributes"); }
42 | }
43 |
44 | public override void Accept(IOracleReferenceVisitor visitor)
45 | {
46 | visitor.VisitTypeReference(this);
47 | }
48 | }
49 |
50 | public abstract class OracleProgramReferenceBase : OracleReference
51 | {
52 | public StatementGrammarNode ParameterListNode { get; set; }
53 |
54 | public IReadOnlyList ParameterReferences { get; set; }
55 |
56 | public abstract OracleProgramMetadata Metadata { get; set; }
57 | }
58 |
59 | public class ProgramParameterReference
60 | {
61 | public static readonly ProgramParameterReference[] EmptyArray = new ProgramParameterReference[0];
62 |
63 | public StatementGrammarNode ParameterNode { get; set; }
64 |
65 | public StatementGrammarNode ValueNode { get; set; }
66 |
67 | public StatementGrammarNode OptionalIdentifierTerminal { get; set; }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleSequenceReference.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 | using SqlPad.Oracle.DataDictionary;
4 |
5 | namespace SqlPad.Oracle.SemanticModel
6 | {
7 | [DebuggerDisplay("OracleSequenceReference (Owner={OwnerNode == null ? null : OwnerNode.Token.Value}; Sequence={ObjectNode.Token.Value})")]
8 | public class OracleSequenceReference : OracleObjectWithColumnsReference
9 | {
10 | private static readonly OracleColumn[] EmptyArray = new OracleColumn[0];
11 |
12 | public override string Name => ObjectNode.Token.Value;
13 |
14 | public override ReferenceType Type => ReferenceType.SchemaObject;
15 |
16 | public override void Accept(IOracleReferenceVisitor visitor)
17 | {
18 | visitor.VisitSequenceReference(this);
19 | }
20 |
21 | protected override IReadOnlyList BuildColumns()
22 | {
23 | return EmptyArray;
24 | }
25 |
26 | protected override IReadOnlyList BuildPseudocolumns()
27 | {
28 | return ((OracleSequence)SchemaObject).Columns;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleSpecialTableReference.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using SqlPad.Oracle.DataDictionary;
5 |
6 | namespace SqlPad.Oracle.SemanticModel
7 | {
8 | [DebuggerDisplay("OracleSpecialTableReference (Alias={Name})")]
9 | public class OracleSpecialTableReference : OracleDataObjectReference
10 | {
11 | public StatementGrammarNode ColumnsClause { get; }
12 |
13 | public OracleSpecialTableReference(OracleReferenceContainer referenceContainer, ReferenceType referenceType, IEnumerable columns, StatementGrammarNode columnsClause)
14 | : base(referenceType)
15 | {
16 | referenceContainer.ObjectReferences.Add(this);
17 | Container = referenceContainer;
18 | ColumnDefinitions = columns.ToArray();
19 | ColumnsClause = columnsClause;
20 | }
21 |
22 | public IReadOnlyList ColumnDefinitions { get; }
23 |
24 | public override string Name => AliasNode?.Token.Value;
25 |
26 | protected override OracleObjectIdentifier BuildFullyQualifiedObjectName()
27 | {
28 | return OracleObjectIdentifier.Create(null, Name);
29 | }
30 |
31 | protected override IReadOnlyList BuildColumns()
32 | {
33 | return ColumnDefinitions.Select(c => c.ColumnDescription).ToArray();
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleStatementSemanticModelFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DatabaseConnection;
4 |
5 | namespace SqlPad.Oracle.SemanticModel
6 | {
7 | public static class OracleStatementSemanticModelFactory
8 | {
9 | public static OracleStatementSemanticModel Build(string statementText, OracleStatement statement, OracleDatabaseModelBase databaseModel)
10 | {
11 | return BuildInternal(statementText, statement, databaseModel, CancellationToken.None);
12 | }
13 |
14 | private static OracleStatementSemanticModel BuildInternal(string statementText, OracleStatement statement, OracleDatabaseModelBase databaseModel, CancellationToken cancellationToken)
15 | {
16 | var semanticModel = statement != null && statement.IsPlSql
17 | ? new OraclePlSqlStatementSemanticModel(statementText, statement, databaseModel)
18 | : new OracleStatementSemanticModel(statementText, statement, databaseModel);
19 | return semanticModel.Build(cancellationToken);
20 | }
21 |
22 | public static Task BuildAsync(string statementText, OracleStatement statement, OracleDatabaseModelBase databaseModel, CancellationToken cancellationToken)
23 | {
24 | return Task.Run(() => BuildInternal(statementText, statement, databaseModel, cancellationToken), cancellationToken);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/OracleTableCollectionReference.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 | using SqlPad.Oracle.DataDictionary;
4 |
5 | namespace SqlPad.Oracle.SemanticModel
6 | {
7 | [DebuggerDisplay("OracleTableCollectionReference (OwnerNode={OwnerNode == null ? null : OwnerNode.Token.Value}; ObjectNode={ObjectNode == null ? null : ObjectNode.Token.Value})")]
8 | public class OracleTableCollectionReference : OracleDataObjectReference
9 | {
10 | private OracleReference _rowSourceReference;
11 |
12 | public OracleReference RowSourceReference
13 | {
14 | get { return _rowSourceReference; }
15 | set
16 | {
17 | _rowSourceReference = value;
18 | OwnerNode = _rowSourceReference.OwnerNode;
19 | ObjectNode = _rowSourceReference.ObjectNode;
20 | Owner = _rowSourceReference.Owner;
21 | }
22 | }
23 |
24 | public override string Name => AliasNode?.Token.Value;
25 |
26 | public override IEnumerable IncludeInnerReferences
27 | {
28 | get
29 | {
30 | yield return this;
31 |
32 | var columnSourceReference = _rowSourceReference as OracleColumnReference;
33 | if (columnSourceReference?.ValidObjectReference is OracleDataObjectReference innerObjectReferences)
34 | {
35 | yield return innerObjectReferences;
36 | }
37 | }
38 | }
39 |
40 | public OracleTableCollectionReference(OracleReferenceContainer referenceContainer) : base(ReferenceType.TableCollection)
41 | {
42 | referenceContainer.ObjectReferences.Add(this);
43 | Container = referenceContainer;
44 | Placement = StatementPlacement.TableReference;
45 | }
46 |
47 | protected override OracleObjectIdentifier BuildFullyQualifiedObjectName()
48 | {
49 | return OracleObjectIdentifier.Create(null, Name);
50 | }
51 |
52 | public override void Accept(IOracleReferenceVisitor visitor)
53 | {
54 | visitor.VisitTableCollectionReference(this);
55 | }
56 |
57 | protected override IReadOnlyList BuildColumns()
58 | {
59 | var columnBuilderVisitor = new OracleColumnBuilderVisitor();
60 | _rowSourceReference?.Accept(columnBuilderVisitor);
61 |
62 | return columnBuilderVisitor.Columns;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/QueryBlockType.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Oracle.SemanticModel
2 | {
3 | public enum QueryBlockType
4 | {
5 | Normal,
6 | CursorParameter,
7 | CommonTableExpression,
8 | ScalarSubquery
9 | }
10 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/ReferenceType.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Oracle.SemanticModel
2 | {
3 | public enum ReferenceType
4 | {
5 | SchemaObject,
6 | CommonTableExpression,
7 | InlineView,
8 | TableCollection,
9 | XmlTable,
10 | JsonTable,
11 | SqlModel,
12 | PivotTable,
13 | HierarchicalClause
14 | }
15 | }
--------------------------------------------------------------------------------
/SqlPad.Oracle/SemanticModel/StatementPlacement.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Oracle.SemanticModel
2 | {
3 | public enum StatementPlacement
4 | {
5 | None,
6 | ValuesClause,
7 | SelectList,
8 | TableReference,
9 | PivotClause,
10 | Where,
11 | GroupBy,
12 | Having,
13 | Join,
14 | OrderBy,
15 | Model,
16 | ConnectBy,
17 | RecursiveSearchOrCycleClause
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/SessionIdentifier.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace SqlPad.Oracle
4 | {
5 | [DebuggerDisplay("SessionIdentifier (Instance={Instance}; SessionId={SessionId})")]
6 | public struct SessionIdentifier
7 | {
8 | public int Instance { get; }
9 |
10 | public int SessionId { get; }
11 |
12 | public SessionIdentifier(int instance, int sessionId)
13 | {
14 | Instance = instance;
15 | SessionId = sessionId;
16 | }
17 |
18 | public bool Equals(SessionIdentifier other)
19 | {
20 | return Instance == other.Instance && SessionId == other.SessionId;
21 | }
22 |
23 | public override bool Equals(object obj)
24 | {
25 | if (ReferenceEquals(null, obj))
26 | {
27 | return false;
28 | }
29 |
30 | return obj is SessionIdentifier && Equals((SessionIdentifier)obj);
31 | }
32 |
33 | public override int GetHashCode()
34 | {
35 | unchecked
36 | {
37 | return (Instance * 397) ^ SessionId;
38 | }
39 | }
40 |
41 | public static bool operator ==(SessionIdentifier left, SessionIdentifier right)
42 | {
43 | return left.Equals(right);
44 | }
45 |
46 | public static bool operator !=(SessionIdentifier left, SessionIdentifier right)
47 | {
48 | return !left.Equals(right);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetGatherTableStats.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | {0}, tabname => '{1}'); END;]]>
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetInsert.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | VALUES ()]]>
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetObjects.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetSelect.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetSelectCount.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Snippets/SnippetTables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Themes/Common.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
24 |
25 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/Themes/ToolTipDataGrid.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
21 |
22 |
25 |
26 |
31 |
32 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ConstraintList.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
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 |
43 |
44 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ConstraintList.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using System.Windows;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ConstraintList
8 | {
9 | public ConstraintList()
10 | {
11 | InitializeComponent();
12 | }
13 |
14 | public static readonly DependencyProperty ConstraintsProperty = DependencyProperty.Register("Constraints", typeof(IEnumerable), typeof(ConstraintList), new FrameworkPropertyMetadata(PropertyChangedCallbackHandler));
15 |
16 | [Bindable(true)]
17 | public IEnumerable Constraints
18 | {
19 | get { return (IEnumerable)GetValue(ConstraintsProperty); }
20 | set { SetValue(ConstraintsProperty, value); }
21 | }
22 |
23 | private static void PropertyChangedCallbackHandler(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
24 | {
25 | var constraintList = (ConstraintList)dependencyObject;
26 | constraintList.DataGrid.ItemsSource = (IEnumerable)args.NewValue;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/IndexList.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using System.Windows;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class IndexList
8 | {
9 | public IndexList()
10 | {
11 | InitializeComponent();
12 | }
13 |
14 | public static readonly DependencyProperty IndexesProperty = DependencyProperty.Register("Indexes", typeof(IEnumerable), typeof(IndexList), new FrameworkPropertyMetadata(PropertyChangedCallbackHandler));
15 |
16 | [Bindable(true)]
17 | public IEnumerable Indexes
18 | {
19 | get { return (IEnumerable)GetValue(IndexesProperty); }
20 | set { SetValue(IndexesProperty, value); }
21 | }
22 |
23 | private static void PropertyChangedCallbackHandler(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
24 | {
25 | var indexList = (IndexList)dependencyObject;
26 | indexList.DataGrid.ItemsSource = (IEnumerable)args.NewValue;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/PartitionList.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows;
3 |
4 | namespace SqlPad.Oracle.ToolTips
5 | {
6 | public partial class PartitionList
7 | {
8 | public PartitionList()
9 | {
10 | InitializeComponent();
11 | }
12 |
13 | public static readonly DependencyProperty TableDetailsProperty = DependencyProperty.Register("TableDetails", typeof(TableDetailsModel), typeof(PartitionList), new FrameworkPropertyMetadata(TableDetailsPropertyChangedCallbackHandler));
14 |
15 | [Bindable(true)]
16 | public TableDetailsModel TableDetails
17 | {
18 | get { return (TableDetailsModel)GetValue(TableDetailsProperty); }
19 | set { SetValue(TableDetailsProperty, value); }
20 | }
21 |
22 | private static void TableDetailsPropertyChangedCallbackHandler(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
23 | {
24 | var partitionList = (PartitionList)dependencyObject;
25 | partitionList.DataContext = args.NewValue;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipAsterisk.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 |
7 | namespace SqlPad.Oracle.ToolTips
8 | {
9 | public partial class ToolTipAsterisk : IToolTip
10 | {
11 | public event EventHandler Pin;
12 |
13 | public Control Control => this;
14 |
15 | public FrameworkElement InnerContent => this;
16 |
17 | public ToolTipAsterisk()
18 | {
19 | InitializeComponent();
20 | }
21 |
22 | public IEnumerable Columns
23 | {
24 | get
25 | {
26 | var sourceModels = (IEnumerable)ItemsControl.ItemsSource;
27 | return sourceModels.Where(m => !m.IsSeparator);
28 | }
29 | set
30 | {
31 | var columnViewModels = new List();
32 |
33 | OracleColumnModel previousModel = null;
34 | foreach (var model in value)
35 | {
36 | if (previousModel != null && previousModel.RowSourceName != model.RowSourceName)
37 | {
38 | columnViewModels.Add(OracleColumnViewModel.CreateSeparator());
39 | }
40 |
41 | columnViewModels.Add(OracleColumnViewModel.FromDataModel(model));
42 |
43 | previousModel = model;
44 | }
45 |
46 | ItemsControl.ItemsSource = columnViewModels;
47 | }
48 | }
49 | }
50 |
51 | public class OracleColumnModel
52 | {
53 | public int ColumnIndex { get; set; }
54 |
55 | public string Name { get; set; }
56 |
57 | public string FullTypeName { get; set; }
58 |
59 | public bool? Nullable { get; set; }
60 |
61 | public string RowSourceName { get; set; }
62 | }
63 |
64 | internal class OracleColumnViewModel : OracleColumnModel
65 | {
66 | public bool IsSeparator { get; private set; }
67 |
68 | public static OracleColumnViewModel CreateSeparator()
69 | {
70 | return new OracleColumnViewModel { IsSeparator = true };
71 | }
72 |
73 | public static OracleColumnViewModel FromDataModel(OracleColumnModel model)
74 | {
75 | return
76 | new OracleColumnViewModel
77 | {
78 | ColumnIndex = model.ColumnIndex,
79 | FullTypeName = model.FullTypeName,
80 | Nullable = model.Nullable,
81 | Name = model.Name.ToSimpleIdentifier(),
82 | RowSourceName = model.RowSourceName
83 | };
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipDatabaseLink.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipDatabaseLink.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DataDictionary;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ToolTipDatabaseLink
8 | {
9 | public ToolTipDatabaseLink(OracleDatabaseLink databaseLink)
10 | {
11 | InitializeComponent();
12 |
13 | DataContext = databaseLink;
14 | }
15 |
16 | protected override Task ExtractDdlAsync(CancellationToken cancellationToken)
17 | {
18 | return ScriptExtractor.ExtractSchemaObjectScriptAsync((OracleDatabaseLink)DataContext, cancellationToken);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipMaterializedView.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using SqlPad.Oracle.DataDictionary;
6 |
7 | namespace SqlPad.Oracle.ToolTips
8 | {
9 | public partial class ToolTipMaterializedView
10 | {
11 | public ToolTipMaterializedView()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | protected override Task ExtractDdlAsync(CancellationToken cancellationToken)
17 | {
18 | return ScriptExtractor.ExtractSchemaObjectScriptAsync(((MaterializedViewDetailsModel)DataContext).MaterializedView, cancellationToken);
19 | }
20 | }
21 |
22 | public class MaterializedViewDetailsModel : TableDetailsModel
23 | {
24 | public OracleMaterializedView MaterializedView
25 | {
26 | get { return (OracleMaterializedView)Table; }
27 | set { Table = value; }
28 | }
29 |
30 | public string MaterializedViewTitle { get; set; }
31 | }
32 |
33 | internal class MaterializedViewPropertyConverter : ValueConverterBase
34 | {
35 | public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
36 | {
37 | if (value is MaterializedViewRefreshMode)
38 | {
39 | return (MaterializedViewRefreshMode)value == MaterializedViewRefreshMode.OnDemand ? "On demand" : "On commit";
40 | }
41 |
42 | var stringValue = (string)value;
43 | return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(stringValue.ToLowerInvariant());
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipObject.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipObject.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ToolTipObject : IToolTip
8 | {
9 | public event EventHandler Pin;
10 |
11 | public ToolTipObject()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | public Control Control => this;
17 |
18 | public FrameworkElement InnerContent => this;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipPartition.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Oracle.ToolTips
2 | {
3 | public partial class ToolTipPartition
4 | {
5 | public ToolTipPartition(PartitionDetailsModelBase dataModel)
6 | {
7 | InitializeComponent();
8 |
9 | DataContext = dataModel;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipSequence.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DataDictionary;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ToolTipSequence
8 | {
9 | public ToolTipSequence(string title, OracleSequence sequence)
10 | {
11 | InitializeComponent();
12 |
13 | LabelTitle.Text = title;
14 |
15 | DataContext = sequence;
16 | }
17 |
18 | protected override Task ExtractDdlAsync(CancellationToken cancellationToken)
19 | {
20 | return ScriptExtractor.ExtractSchemaObjectScriptAsync((OracleSequence)DataContext, cancellationToken);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipView.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipView.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using SqlPad.Oracle.DataDictionary;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ToolTipView
8 | {
9 | public ToolTipView()
10 | {
11 | InitializeComponent();
12 | }
13 |
14 | protected override Task ExtractDdlAsync(CancellationToken cancellationToken)
15 | {
16 | return ScriptExtractor.ExtractSchemaObjectScriptAsync(((ObjectDetailsModel)DataContext).Object, cancellationToken);
17 | }
18 | }
19 |
20 | public class ObjectDetailsModel : ModelWithConstraints, IModelWithComment
21 | {
22 | private string _comment;
23 |
24 | public OracleObject Object { get; set; }
25 |
26 | public string Title { get; set; }
27 |
28 | public string Comment
29 | {
30 | get { return _comment; }
31 | set { UpdateValueAndRaisePropertyChanged(ref _comment, value); }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/SqlPad.Oracle/ToolTips/ToolTipViewColumn.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 |
5 | namespace SqlPad.Oracle.ToolTips
6 | {
7 | public partial class ToolTipViewColumn : IToolTip
8 | {
9 | public event EventHandler Pin;
10 |
11 | public ToolTipViewColumn(ColumnDetailsModel dataModel)
12 | {
13 | InitializeComponent();
14 |
15 | DataContext = dataModel;
16 | }
17 |
18 | public Control Control => this;
19 |
20 | public FrameworkElement InnerContent => this;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SqlPad.Test/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SqlPad.Test/ConsoleTraceListenerTestFixture.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using NUnit.Framework;
3 |
4 | namespace SqlPad.Test
5 | {
6 | [SetUpFixture]
7 | public class ConsoleTraceListenerTestFixture
8 | {
9 | [OneTimeSetUp]
10 | public void SetUp()
11 | {
12 | Trace.Listeners.Add(new ConsoleTraceListener());
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/SqlPad.Test/EditorNavigationServiceTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NUnit.Framework;
3 | using Shouldly;
4 |
5 | namespace SqlPad.Test
6 | {
7 | [TestFixture]
8 | public class EditorNavigationServiceTest
9 | {
10 | [SetUp]
11 | public void SetUp()
12 | {
13 | EditorNavigationService.Initialize();
14 | }
15 |
16 | [Test, STAThread]
17 | public void TestInitializedEditorNavigationService()
18 | {
19 | EditorNavigationService.IsEnabled.ShouldBeTrue();
20 | EditorNavigationService.GetNextEdit().ShouldBeNull();
21 | Should.Throw(() => EditorNavigationService.GetPreviousEdit());
22 | }
23 |
24 | [Test, STAThread]
25 | public void TestRegisterDocumentCursorPosition()
26 | {
27 | var workingDocument = new WorkDocument();
28 | const int originalPosition = 10;
29 | const int position2 = 99;
30 | const int lastPosition = 43;
31 | EditorNavigationService.RegisterDocumentCursorPosition(workingDocument, originalPosition);
32 | EditorNavigationService.RegisterDocumentCursorPosition(workingDocument, position2);
33 | EditorNavigationService.RegisterDocumentCursorPosition(workingDocument, lastPosition);
34 | EditorNavigationService.GetNextEdit().ShouldBeNull();
35 | var previousEdit = EditorNavigationService.GetPreviousEdit();
36 | previousEdit.ShouldNotBeNull();
37 | previousEdit.Document.ShouldBe(workingDocument);
38 | previousEdit.CursorPosition.ShouldBe(position2);
39 | previousEdit = EditorNavigationService.GetPreviousEdit();
40 | previousEdit.ShouldNotBeNull();
41 | previousEdit.Document.ShouldBe(workingDocument);
42 | previousEdit.CursorPosition.ShouldBe(originalPosition);
43 | previousEdit = EditorNavigationService.GetPreviousEdit();
44 | previousEdit.ShouldNotBeNull();
45 | previousEdit.Document.ShouldBe(workingDocument);
46 | previousEdit.CursorPosition.ShouldBe(originalPosition);
47 |
48 | var nextEdit = EditorNavigationService.GetNextEdit();
49 | nextEdit.ShouldNotBeNull();
50 | nextEdit.Document.ShouldBe(workingDocument);
51 | nextEdit.CursorPosition.ShouldBe(position2);
52 | nextEdit = EditorNavigationService.GetNextEdit();
53 | nextEdit.ShouldNotBeNull();
54 | nextEdit.Document.ShouldBe(workingDocument);
55 | nextEdit.CursorPosition.ShouldBe(lastPosition);
56 | EditorNavigationService.GetNextEdit().ShouldBeNull();
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SqlPad.Test/EditorTest.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using NUnit.Framework;
3 | using Shouldly;
4 | using SqlPad.Commands;
5 |
6 | namespace SqlPad.Test
7 | {
8 | [TestFixture]
9 | public class EditorTest
10 | {
11 | private SqlTextEditor _editor;
12 |
13 | [SetUp]
14 | public void SetUp()
15 | {
16 | _editor = new SqlTextEditor();
17 | }
18 |
19 | [Test, Apartment(ApartmentState.STA)]
20 | public void SetLineDuplicationAtLineBeginning()
21 | {
22 | _editor.Text = "SELECT * FROM SELECTION;";
23 | GenericCommandHandler.DuplicateText(_editor.TextArea, null);
24 |
25 | _editor.Text.ShouldBe("SELECT * FROM SELECTION;\nSELECT * FROM SELECTION;");
26 | _editor.CaretOffset.ShouldBe(25);
27 | }
28 |
29 | [Test, Apartment(ApartmentState.STA)]
30 | public void SetLineDuplicationAtLineEnd()
31 | {
32 | _editor.Text = "SELECT * FROM SELECTION;";
33 | _editor.CaretOffset = 24;
34 | GenericCommandHandler.DuplicateText(_editor.TextArea, null);
35 |
36 | _editor.Text.ShouldBe("SELECT * FROM SELECTION;\nSELECT * FROM SELECTION;");
37 | _editor.CaretOffset.ShouldBe(49);
38 | }
39 |
40 | [Test, Apartment(ApartmentState.STA)]
41 | public void SetSelectionDuplicate()
42 | {
43 | _editor.Text = "SELECT * FROM SELECTION;";
44 | _editor.CaretOffset = 13;
45 | _editor.SelectionLength = 10;
46 | _editor.SelectedText.ShouldBe(" SELECTION");
47 | GenericCommandHandler.DuplicateText(_editor.TextArea, null);
48 |
49 | _editor.Text.ShouldBe("SELECT * FROM SELECTION SELECTION;");
50 | _editor.CaretOffset.ShouldBe(33);
51 | }
52 |
53 | [Test, Apartment(ApartmentState.STA)]
54 | public void TestBlockComments()
55 | {
56 | _editor.Text = "SELECT * FROM SELECTION;\nSELECT * FROM RESPONDENTBUCKET";
57 | _editor.CaretOffset = 13;
58 | _editor.SelectionLength = 35;
59 |
60 | GenericCommandHandler.HandleBlockComments(_editor.TextArea, null);
61 |
62 | _editor.Text.ShouldBe("SELECT * FROM/* SELECTION;\nSELECT * FROM RESPONDEN*/TBUCKET");
63 | _editor.CaretOffset.ShouldBe(50);
64 | _editor.SelectionLength.ShouldBe(0);
65 | }
66 |
67 | [Test, Apartment(ApartmentState.STA)]
68 | public void TestLineComments()
69 | {
70 | _editor.Text = "SELECT * FROM SELECTION;\nSELECT * FROM RESPONDENTBUCKET";
71 | _editor.CaretOffset = 13;
72 | _editor.SelectionLength = 35;
73 |
74 | GenericCommandHandler.HandleLineComments(_editor.TextArea, null);
75 |
76 | _editor.Text.ShouldBe("--SELECT * FROM SELECTION;\n--SELECT * FROM RESPONDENTBUCKET");
77 | _editor.CaretOffset.ShouldBe(52);
78 | _editor.SelectionLength.ShouldBe(0);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/SqlPad.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("SqlPad.Test")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("SqlPad.Test")]
12 | [assembly: AssemblyCopyright("Copyright © 2016")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("3da8b989-03bb-4493-90af-995d38d9ba1e")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/SqlPad.Test/TemporaryDirectoryTestFixture.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.IO;
3 | using NUnit.Framework;
4 |
5 | namespace SqlPad.Test
6 | {
7 | public abstract class TemporaryDirectoryTestFixture
8 | {
9 | protected string TempDirectoryName;
10 |
11 | [SetUp]
12 | public void SetUp()
13 | {
14 | TempDirectoryName = TestFixture.SetupTestDirectory();
15 | ConfigurationProvider.SetUserDataFolder(TempDirectoryName);
16 | }
17 |
18 | [TearDown]
19 | public void TearDown()
20 | {
21 | WorkDocumentCollection.ReleaseConfigurationLock();
22 | Directory.Delete(TempDirectoryName, true);
23 | Trace.WriteLine($"Test temp directory '{TempDirectoryName}' has been deleted. ");
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/SqlPad.Test/TestFixture.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 |
5 | namespace SqlPad.Test
6 | {
7 | public static class TestFixture
8 | {
9 | public static string SetupTestDirectory()
10 | {
11 | var tempDirectoryName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
12 | Directory.CreateDirectory(tempDirectoryName);
13 | Trace.WriteLine($"Test temp directory '{tempDirectoryName}' has been created. ");
14 | return tempDirectoryName;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/SqlPad/Archive.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/SqlPad/Archive.ico
--------------------------------------------------------------------------------
/SqlPad/AssemblyBuildInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace SqlPad
5 | {
6 | [AttributeUsage(AttributeTargets.Assembly)]
7 | public class AssemblyBuildInfo : Attribute
8 | {
9 | public const string TimestampMask = "yyyy-MM-dd HH:mm:ss";
10 |
11 | public AssemblyBuildInfo(string lastGitCommitHash, string timestampString)
12 | {
13 | VersionTimestampString = timestampString;
14 | VersionTimestamp = DateTime.ParseExact(timestampString, TimestampMask, CultureInfo.InvariantCulture);
15 | LastGitCommitHash = lastGitCommitHash;
16 | }
17 |
18 | public DateTime VersionTimestamp { get; private set; }
19 |
20 | public string VersionTimestampString { get; private set; }
21 |
22 | public string LastGitCommitHash { get; private set; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/SqlPad/BindVariableModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace SqlPad
5 | {
6 | public class BindVariableModel : ModelBase
7 | {
8 | public BindVariableModel(BindVariableConfiguration bindVariable)
9 | {
10 | BindVariable = bindVariable;
11 | }
12 |
13 | public BindVariableConfiguration BindVariable { get; }
14 |
15 | public bool IsFilePath
16 | {
17 | get { return BindVariable.IsFilePath; }
18 | set { BindVariable.IsFilePath = value; }
19 | }
20 |
21 | public string Name => BindVariable.Name;
22 |
23 | public ICollection DataTypes => BindVariable.DataTypes.Values;
24 |
25 | public object Value
26 | {
27 | get { return BindVariable.Value; }
28 | set
29 | {
30 | if (BindVariable.Value == value)
31 | {
32 | return;
33 | }
34 |
35 | BindVariable.Value = value;
36 | RaisePropertyChanged(nameof(Value));
37 | }
38 | }
39 |
40 | public Type InputType => BindVariable.DataTypes[BindVariable.DataType].InputType;
41 |
42 | public BindVariableType DataType
43 | {
44 | get { return BindVariable.DataTypes[BindVariable.DataType]; }
45 | set
46 | {
47 | if (BindVariable.DataType == value.Name)
48 | {
49 | return;
50 | }
51 |
52 | var previousInputType = BindVariable.DataTypes[value.Name].InputType;
53 |
54 | BindVariable.DataType = value.Name;
55 |
56 | if (previousInputType != InputType)
57 | {
58 | Value = null;
59 | RaisePropertyChanged(nameof(InputType));
60 | }
61 |
62 | RaisePropertyChanged(nameof(DataType));
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SqlPad/Chart.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Husqvik/SQLPad/c858b567aa01be4d5920cd9f9fc05c65c939a584/SqlPad/Chart.ico
--------------------------------------------------------------------------------
/SqlPad/ClipboardManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 | using System.Windows.Interop;
5 |
6 | namespace SqlPad
7 | {
8 | public class ClipboardManager
9 | {
10 | private static readonly ClipboardManager Instance = new ClipboardManager();
11 | private static readonly IntPtr WndProcSuccess = IntPtr.Zero;
12 |
13 | public static event EventHandler ClipboardChanged;
14 |
15 | private ClipboardManager()
16 | {
17 | }
18 |
19 | public static void RegisterWindow(Window window)
20 | {
21 | var source = PresentationSource.FromVisual(window) as HwndSource;
22 | if (source == null)
23 | {
24 | throw new ArgumentException("Window must be initialized first. ", nameof(window));
25 | }
26 |
27 | source.AddHook(Instance.WndProc);
28 |
29 | var windowHandle = new WindowInteropHelper(window).Handle;
30 |
31 | NativeMethods.AddClipboardFormatListener(windowHandle);
32 | }
33 |
34 | public static bool TryGetClipboardText(out string text)
35 | {
36 | text = null;
37 |
38 | try
39 | {
40 | text = Clipboard.GetText();
41 | return !String.IsNullOrEmpty(text);
42 | }
43 | catch (COMException) { }
44 | catch (OutOfMemoryException) { }
45 |
46 | return false;
47 | }
48 |
49 | private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
50 | {
51 | if (msg == NativeMethods.ClipboardUpdate)
52 | {
53 | ClipboardChanged?.Invoke(this, EventArgs.Empty);
54 | handled = true;
55 | }
56 |
57 | return WndProcSuccess;
58 | }
59 |
60 | private static class NativeMethods
61 | {
62 | public const int ClipboardUpdate = 0x031D;
63 |
64 | [DllImport("user32.dll", SetLastError = true)]
65 | [return: MarshalAs(UnmanagedType.Bool)]
66 | public static extern bool AddClipboardFormatListener(IntPtr hwnd);
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/SqlPad/ColumnHeader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Data;
4 |
5 | namespace SqlPad
6 | {
7 | public class ColumnHeader
8 | {
9 | public int ColumnIndex { get; set; }
10 |
11 | public string Name { get; set; }
12 |
13 | public string DatabaseDataType { get; set; }
14 |
15 | public Type DataType { get; set; }
16 |
17 | public IValueConverter CustomConverter { get; set; }
18 |
19 | public IReadOnlyCollection ParentReferenceDataSources { get; set; }
20 |
21 | public bool IsNumeric => DataType.In(typeof(Decimal), typeof(Int16), typeof(Int32), typeof(Int64), typeof(Byte), typeof(Single), typeof(Double));
22 |
23 | public override string ToString()
24 | {
25 | return Name;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/SqlPad/CommandSettingsModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Windows.Controls;
5 |
6 | namespace SqlPad
7 | {
8 | public class CommandSettingsModel : ModelBase
9 | {
10 | private string _value = String.Empty;
11 |
12 | public Func UseDefaultSettings { get; set; }
13 |
14 | public string Title { get; set; } = String.Empty;
15 |
16 | public string Heading { get; set; } = String.Empty;
17 |
18 | public string Description { get; set; } = String.Empty;
19 |
20 | public bool IsTextInputVisible { get; set; } = true;
21 |
22 | public string Value
23 | {
24 | get { return _value; }
25 | set { UpdateValueAndRaisePropertyChanged(ref _value, value); }
26 | }
27 |
28 | public IDictionary BooleanOptions { get; } = new Dictionary();
29 |
30 | public ValidationRule ValidationRule { get; set; }
31 |
32 | public void AddBooleanOption(BooleanOption option)
33 | {
34 | BooleanOptions.Add(option.OptionIdentifier, option);
35 | }
36 | }
37 |
38 | [DebuggerDisplay("BooleanOption(OptionIdentifier={OptionIdentifier}; Value={Value})")]
39 | public class BooleanOption : ModelBase
40 | {
41 | private bool _value;
42 |
43 | public BooleanOption()
44 | {
45 | IsEnabled = true;
46 | }
47 |
48 | public bool Value
49 | {
50 | get { return _value; }
51 | set { UpdateValueAndRaisePropertyChanged(ref _value, value); }
52 | }
53 |
54 | public string OptionIdentifier { get; set; }
55 |
56 | public object DescriptionContent { get; set; }
57 |
58 | public object Tag { get; set; }
59 |
60 | public bool IsEnabled { get; set; }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/SqlPad/Commands/DiagnosticCommands.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Input;
2 | using ICSharpCode.AvalonEdit;
3 |
4 | namespace SqlPad.Commands
5 | {
6 | internal static class DiagnosticCommands
7 | {
8 | public static RoutedCommand ShowTokenCommand = new RoutedCommand("ShowTokens", typeof(TextEditor), new InputGestureCollection { new KeyGesture(Key.T, ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift) });
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/SqlPad/Commands/ICommandFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace SqlPad.Commands
4 | {
5 | public interface ICommandFactory
6 | {
7 | ICollection CommandHandlers { get; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/SqlPad/Commands/ICommandSettings.cs:
--------------------------------------------------------------------------------
1 | namespace SqlPad.Commands
2 | {
3 | public interface ICommandSettingsProvider
4 | {
5 | bool GetSettings();
6 |
7 | CommandSettingsModel Settings { get; }
8 | }
9 |
10 | public interface ICommandSettingsProviderFactory
11 | {
12 | ICommandSettingsProvider CreateCommandSettingsProvider(CommandSettingsModel settings);
13 | }
14 | }
--------------------------------------------------------------------------------
/SqlPad/CompilationErrorArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SqlPad
4 | {
5 | public class CompilationErrorArgs : EventArgs
6 | {
7 | public CompilationError CompilationError { get; private set; }
8 |
9 | public CompilationErrorArgs(CompilationError compilationError)
10 | {
11 | CompilationError = compilationError ?? throw new ArgumentNullException(nameof(compilationError));
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/SqlPad/ComplexTypeViewer.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 |
6 | namespace SqlPad
7 | {
8 | public partial class ComplexTypeViewer
9 | {
10 | public static readonly DependencyProperty ComplexTypeProperty = DependencyProperty.Register(nameof(ComplexType), typeof(IComplexType), typeof(ComplexTypeViewer), new FrameworkPropertyMetadata());
11 |
12 | internal EventHandler ResultGridBeginningEditCancelTextInputHandler => App.DataGridBeginningEditCancelTextInputHandlerImplementation;
13 |
14 | public ComplexTypeViewer()
15 | {
16 | InitializeComponent();
17 | }
18 |
19 | [Bindable(true)]
20 | public IComplexType ComplexType
21 | {
22 | get { return (IComplexType)GetValue(ComplexTypeProperty); }
23 | set { SetValue(ComplexTypeProperty, value); }
24 | }
25 |
26 | private void ComplexTypeViewerGridSortingHandler(object sender, DataGridSortingEventArgs e)
27 | {
28 | if (!Equals(e.Column, AttributeNameColumn))
29 | {
30 | e.Handled = true;
31 | }
32 | }
33 | }
34 |
35 | /*internal class CustomTypeDataTemplateSelector : DataTemplateSelector
36 | {
37 | public bool IsEditing { get; set; }
38 |
39 | public override DataTemplate SelectTemplate(object item, DependencyObject container)
40 | {
41 | var collectionValue = item as ICollectionValue;
42 | var complexType = item as IComplexType;
43 |
44 | var complexTypeViewer = WpfExtensions.FindParentVisual(container);
45 | var templateName = String.Format("PrimitiveValueType{0}Template", IsEditing ? "Editing" : null);
46 |
47 | return (DataTemplate)complexTypeViewer.Resources[templateName];
48 | }
49 | }*/
50 | }
51 |
--------------------------------------------------------------------------------
/SqlPad/Configuration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/SqlPad/Configuration.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/SqlPad/DataExport/DataExportHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Windows.Controls;
6 |
7 | namespace SqlPad.DataExport
8 | {
9 | internal static class DataExportHelper
10 | {
11 | public static IReadOnlyList GetOrderedExportableColumns(DataGrid dataGrid)
12 | {
13 | return
14 | dataGrid.Columns
15 | .OrderBy(c => c.DisplayIndex)
16 | .Select(c => c.Header as ColumnHeader)
17 | .Where(h => h != null)
18 | .ToArray();
19 | }
20 |
21 | public static TextWriter InitializeWriter(string fileName, Stream stream)
22 | {
23 | return String.IsNullOrEmpty(fileName) ? new StreamWriter(stream) : File.CreateText(fileName);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SqlPad/DataExport/IDataExporter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace SqlPad.DataExport
7 | {
8 | public interface IDataExporter
9 | {
10 | string Name { get; }
11 |
12 | string FileNameFilter { get; }
13 |
14 | string FileExtension { get; }
15 |
16 | bool HasAppendSupport { get; }
17 |
18 | Task StartExportAsync(ExportOptions options, IReadOnlyList columns, IDataExportConverter dataExportConverter, CancellationToken cancellationToken);
19 | }
20 |
21 | public interface IDataExportContext : IDisposable
22 | {
23 | long CurrentRowIndex { get; }
24 |
25 | Task AppendRowsAsync(IEnumerable