Compare commits

..

100 commits

Author SHA1 Message Date
Sal
273666202c update count label correctly 2026-01-12 15:20:48 -05:00
Sal
58da66fec6 Merge branch 'v4.0.0-release' of https://github.com/mukunku/ParquetViewer into v4.0.0-release 2026-01-12 14:54:30 -05:00
Sal
58237ae76f lint 2026-01-12 14:54:23 -05:00
github-actions[bot]
2f2767a7ac Auto-generated file update 2026-01-12 19:48:54 +00:00
Sal
e0f4ffbd15 proper start location 2026-01-12 14:48:35 -05:00
Sal
42688c8ea7 better handle huggingface middle-click shortcut 2026-01-12 14:39:22 -05:00
Sal
d9da431090 add copy/paste context menu to query editor 2026-01-12 14:32:27 -05:00
Sal
f21b342530 use ready to run and only publish self contained exe's now :( 2026-01-11 17:56:50 -05:00
Sal
afc1716411 update build process to net10 2026-01-11 17:21:24 -05:00
Sal
3c8990d9c8 more cleanup 2026-01-11 16:37:02 -05:00
Sal
491d949625 Merge branch 'v4.0.0-release' of https://github.com/mukunku/ParquetViewer into v4.0.0-release 2026-01-11 16:35:01 -05:00
Sal
66e65efdb0 ParquetViewer wouldn't be here today without Parquet.NET but I think it's time to remove this special thanks. I hope this doesn't come across the wrong way <3 2026-01-11 16:34:48 -05:00
github-actions[bot]
d6280f25cf Auto-generated file update 2026-01-11 21:32:24 +00:00
Sal
9523ef3730 Merge branch 'v4.0.0-release' of https://github.com/mukunku/ParquetViewer into v4.0.0-release 2026-01-11 16:32:05 -05:00
Sal
498d01b481 use correct date wrapper for query editor grid 2026-01-11 16:31:58 -05:00
github-actions[bot]
a6d74d4f54 Auto-generated file update 2026-01-11 19:19:41 +00:00
Sal
e3eb7d1ed0 Merge branch 'v4.0.0-release' of https://github.com/mukunku/ParquetViewer into v4.0.0-release 2026-01-11 14:19:23 -05:00
Sal
cbc5195820 adjust translations workflow 2026-01-11 14:19:14 -05:00
github-actions[bot]
4cdd0a63a6 Auto-generated file update 2026-01-11 19:15:47 +00:00
Sal
b22374120f Merge branch 'v4.0.0-release' of https://github.com/mukunku/ParquetViewer into v4.0.0-release 2026-01-11 14:15:30 -05:00
Sal
8405eab596 fix build 2026-01-11 14:13:09 -05:00
Sal
775e1c8d6e remove the concept of unsupported fields (!!) 2026-01-11 14:11:56 -05:00
Sal
a882b13f3c confirmed todo 2026-01-11 14:02:29 -05:00
github-actions[bot]
d17b84b4ae Auto-generated file update 2026-01-11 18:51:05 +00:00
Sal
6f99e53d16 query editor theme and usability improvements 2026-01-11 13:50:42 -05:00
Sal
823ca7c4a7 fix merge errors 2026-01-11 13:39:27 -05:00
Sal
8af083d0b8 merge main 2026-01-11 13:27:22 -05:00
Sal
898bdc0e6b gracefully fail when byte[] types are in query result 2026-01-11 13:11:25 -05:00
Sal
eb2c595b1e re-implement parquet exports via parquetnet. duckdb exports still needs to be implemented 2026-01-11 12:54:06 -05:00
Sal
3ac6830186 fix map type for query editor 2026-01-11 11:25:56 -05:00
Sal
eb16181c97 adjust max window sizes 2026-01-10 22:57:49 -05:00
Sal
93084d405d theme the query editor 2026-01-10 22:30:48 -05:00
Sal
83022a780b localize query editor 2026-01-10 21:14:04 -05:00
Sal
256fbe3ba4 capture analytics 2026-01-10 20:48:01 -05:00
Sal
cfdb9f4ad6 simplify types 2026-01-10 20:33:35 -05:00
Sal
0ce5aea68c better ex handling 2026-01-10 20:12:36 -05:00
Sal
32def4efcd create new query editor tool 2026-01-10 19:11:24 -05:00
Sal
d651996fe1 dotnet format 2026-01-06 18:02:31 -05:00
Sal
ab60c83fac add metadata test 2026-01-06 12:10:16 -05:00
Sal
5598829b91 fix detailed metadata resolution for parquetnet 2026-01-06 11:48:22 -05:00
Sal
7ca9a26bbb deserialize column stat values 2026-01-06 11:11:31 -05:00
Sal
5684fbd153 cleanup and more tests 2026-01-05 22:03:00 -05:00
Sal
98e65f843e improve duckdb engine 2026-01-05 21:42:35 -05:00
Sal
2dad1993b0 improve byte[] compatibility 2026-01-05 21:12:14 -05:00
Sal
5c2107c6e4 capture engine usage in amplitude and separate exceptions for each engine 2026-01-05 15:04:11 -05:00
Sal
8228a8344f better duckdb fallback logic 2026-01-05 09:17:45 -05:00
Sal
c42d37e6e3 add more tests for files we support now thanks to duckdb 2026-01-04 23:00:18 -05:00
Sal
76b5ecd4ce add automatic duckdb fallback when opening files 2026-01-04 22:44:38 -05:00
Sal
a903a96e85 fix sql create script 2026-01-04 20:54:57 -05:00
Sal
2a348133f8 upgrade to .net 10 2026-01-04 20:16:21 -05:00
Sal
86c431fcd6 custom metadata changes 2026-01-04 19:30:17 -05:00
Sal
1e07a838c2 this is cleaner 2026-01-03 16:41:41 -05:00
Sal
006f63d02b moar cleanup 2026-01-03 16:36:26 -05:00
Sal
b4af8c13da cleanup 2026-01-03 02:04:08 -05:00
Sal
1216238c54 byte array support for duckdb 2026-01-02 13:56:07 -05:00
Sal
c2bd64939f implement custom metadata support for DuckDB 2026-01-02 13:16:32 -05:00
Sal
2ac3ddbded all tests are green! 2026-01-02 12:06:55 -05:00
Sal
ff298b8db6 mostly green tests! 2026-01-02 11:48:18 -05:00
Sal
fb94ce4cf4 merge 3.5.1 2025-12-31 19:48:40 -05:00
Sal
333c5e36d2 moar duckdb implementation 2025-12-31 19:04:55 -05:00
Sal
f6994de30b
Delete src/ParquetViewer/Resources/localization-icon.ico 2025-12-31 15:42:25 -05:00
Sal
d64e338a48 widen labels a bit more 2025-12-31 13:34:00 -05:00
Sal
4517f61083 Merge branch 'v3.5.1-release' of https://github.com/mukunku/ParquetViewer into v3.5.1-release 2025-12-31 13:16:01 -05:00
Sal
4ddd292fa5 trigger builds 2025-12-31 13:15:50 -05:00
github-actions[bot]
d9d88d0380 Auto-generated file update 2025-12-31 18:14:33 +00:00
Sal
d81faf32e4 moar translations 2025-12-31 13:14:11 -05:00
Sal
43dc91a12f Merge branch 'v3.5.1-release' of https://github.com/mukunku/ParquetViewer into v3.5.1-release 2025-12-31 11:20:53 -05:00
Sal
f139165091 trigger build 2025-12-31 11:20:48 -05:00
github-actions[bot]
19f3922eb6 Auto-generated file update 2025-12-31 16:20:24 +00:00
Sal
7a7b1ea686 Merge branch 'v3.5.1-release' of https://github.com/mukunku/ParquetViewer into v3.5.1-release 2025-12-31 11:20:02 -05:00
Sal
468751d9a7 localize unhandled exception message 2025-12-31 11:19:55 -05:00
github-actions[bot]
0e2992a3b7 Auto-generated file update 2025-12-31 15:49:29 +00:00
Sal
7477130a66 actually allow cancellation of parquet export 2025-12-31 10:45:38 -05:00
Sal
9b9e88cb84 simplify string formatting 2025-12-31 10:12:59 -05:00
Sal
c5ef222246 moar translations 2025-12-31 09:51:05 -05:00
Sal
573be69574 create 100k rowgroups when exporting data to parquet format 2025-12-31 09:46:36 -05:00
Sal
098aab64a1 update build flags 2025-12-30 19:45:31 -05:00
Sal
8c029a7b8b update workflow 2025-12-30 18:15:25 -05:00
Sal
19aff50a99 log exe size after compile 2025-12-30 18:10:06 -05:00
Sal
13c6442469 remove solution items 2025-12-30 18:03:17 -05:00
Sal
150fad330a remove duplicate resx file causing build failures 2025-12-30 17:30:11 -05:00
Sal
c63a9c581b Merge branch 'v3.5.1-release' of https://github.com/mukunku/ParquetViewer into v3.5.1-release 2025-12-30 16:23:37 -05:00
Sal
0ce20851b6 add issue template for translations 2025-12-30 16:22:57 -05:00
github-actions[bot]
e78b6fb99c Auto-generated file update 2025-12-30 21:10:25 +00:00
Sal
6037e8818a tweak workflow 2025-12-30 16:10:08 -05:00
Sal
f8916dda84 create workflow to automatically generate a translation template. 2025-12-30 16:08:27 -05:00
Sal
0e5bdc70cb fix button text alignment 2025-12-30 16:00:25 -05:00
Sal
076bcdee0d reset default designer language to english 2025-12-30 15:57:38 -05:00
Sal
dd5f389ff3 add comments 2025-12-30 15:39:58 -05:00
Sal
1c30767d2e better localization for custom date format form 2025-12-30 14:59:20 -05:00
Sal
c48e7ceedc add bytearrayvalue truncation test 2025-12-30 14:37:05 -05:00
Sal
c1706b638c add amplitude user property for ui language 2025-12-30 14:27:24 -05:00
Sal
5df24f8fc7 tweak filter query area width in mainform 2025-12-30 12:46:50 -05:00
Sal
8c7661cae9 add language toolstrip item 2025-12-30 12:33:55 -05:00
Sal
7114689c3f localize gridview better 2025-12-30 08:45:19 -05:00
Sal
1df9edc6f6 address random exceptions i found in amplitude 2025-12-29 22:52:22 -05:00
Sal
9593df5d34 localize some exceptions 2025-12-29 21:00:58 -05:00
Sal
02ab78410a moar localization that i missed 2025-12-29 20:54:53 -05:00
Sal
aaf363ac61 add internationalization support (#145)
address #169
2025-12-29 20:39:51 -05:00
Sal
27fbf32c4d rough duckdb functionality 2025-11-28 12:49:17 -05:00
35 changed files with 2737 additions and 1054 deletions

View file

@ -59,6 +59,7 @@
"MainForm.resx","newToolStripMenuItem.Text",,"&New","Yeni",""
"MainForm.resx","openFolderToolStripMenuItem.Text",,"&Open Folder","Klasör Aç",""
"MainForm.resx","openFolderToolStripMenuItem.ToolTipText",,"All parquet files in the folder must have the same schema","Klasördeki tüm parquet dosyaları aynı veri şemasına sahip olmalıdır",""
"MainForm.resx","openQueryEditorToolToolStripMenuItem.Text",,"Query Editor (Beta)","Sorgu Editörü (Beta)",""
"MainForm.resx","openToolStripMenuItem.Text",,"&Open File","Dosya Aç",""
"MainForm.resx","outOfStatusBarLabel.Text",,"Out of:","Toplam:",""
"MainForm.resx","recordsTextStatusBarLabel.Text",,"Results","Sonuç",""
@ -76,6 +77,19 @@
"MetadataViewer.resx","$this.Text",,"Parquet Metadata Viewer","Parquet Metadata Önizleyicisi",""
"MetadataViewer.resx","closeButton.Text",,"Close","Kapat",""
"MetadataViewer.resx","loadingTab.Text",,"Loading...","Yükleniyor...",""
"QueryEditor.resx","$this.Text",,"ParquetViewer - Query Editor (Powered by DuckDB)","ParquetViewer - Sorgu Editörü (DuckDB Desteğiyle)",""
"QueryEditor.resx","copyTextMenuItem.Text",,"Copy","Kopyala",""
"QueryEditor.resx","executeQueryButton.Text",,"Execute","İşle",""
"QueryEditor.resx","pasteTextMenuItem.Text",,"Paste","Yapıştır",""
"QueryEditor.resx","queryExecutionStatusLabel.Text",,"Running:","İşleniyor:",""
"QueryEditor.resx","querySyntaxDocsButton.Text",,"Query Syntax","Sorgu Söz Dizimi",""
"QueryEditor.resx","toolStripStatusLabel1.Text",,"Showing:","Gösterilen:",""
"QueryEditor.resx","toolStripStatusLabel2.Text",,"Results","Sonuç",""
"QueryEditor.resx","zoomPercentageDropDown.Text",,"Query Zoom: 100%","Sorgu Zumu: 100%",""
"QuickPeekForm.resx","$this.Text",,"Quick Peek","Hızlı Önizleme",""
"QuickPeekForm.resx","copyToClipboardToolStripMenuItem.Text",,"Copy to clipboard","Panoya kopyala",""
"QuickPeekForm.resx","saveImageToFileButton.Text",,"Save as PNG","PNG olarak Kaydet",""
"QuickPeekForm.resx","takeMeBackLinkLabel.Text",,"<<< back","<<< geri",""
"Errors.resx","CopyAsWhereTooLargeErrorMessage","Shown when the user right-click's on too many cells and selects the Copy as WHERE... option","The selected data is too large. Please select less cells.","Çok fazla veri seçili. Lütfen daha az hücre seçin.",""
"Errors.resx","CopyAsWhereTooLargeErrorTitle","Shown when the user right-click's on too many cells and selects the Copy as WHERE... option","Copy to clipboard failed","Panoya kopyalama başarısız oldu",""
"Errors.resx","CopyErrorMessageText","Shown in the messagebox for unhandled exceptions to teach users how to copy the error text","(CTRL+C to copy)","(Kopyalamak için CTRL+C)",""
@ -197,7 +211,6 @@ Bu ayarı Yardim → Hakkinda sayfasında da yapabilirsiniz.",""
"Strings.resx","FileExtensionAssociationPromptTitle","Message box title shown when we ask the user if they'd like to associate .parquet files with ParquetViewer","ParquetViewer file association request","ParquetViewer varsayılan uygulama isteği",""
"Strings.resx","FileExtensionAssociationSucceededMessage","Shown when file association succeeds AFTER we ask the user if they'd like to associate ParquetViewer with parquet files","Success! ParquetViewer is now your default application for .parquet files.","Uzantı ilişkilendirmesi başarılı oldu! ParquetViewer .parquet dosyaları için varsayılan uygulamanız olarak ayarlanmıştır.",""
"Strings.resx","FileExtensionAssociationSucceededTitle","Shown when file association succeeds AFTER we ask the user if they'd like to associate ParquetViewer with parquet files","File association succeeded","Uzantı ilişkilendirmesi başarılı",""
"Strings.resx","FrozenColumnText","When the user right-clicks on a column header this is the text shown for freezing the column. Freezing a column makes it so it is always visible no matter how much you scroll horizontally.","Frozen","Dondur",""
"Strings.resx","ImageSavedToDiskMessage","Shown when an image is successfully saved to disk from the quick peek form","Image saved to {0}","Görüntü kaydedildi: {0}",""
"Strings.resx","ImageSavedToDiskTitle","Shown when an image is successfully saved to disk from the quick peek form","Save complete","Kayıt tamamlandı",""
"Strings.resx","IndexingDataLabelText","Text shown while data is being indexed","Indexing","Dizinleniyor",""
@ -269,7 +282,3 @@ Onun yerine sonuçlari {2} dosyasına aktarmak ister misiniz?",""
"Strings.resx","TooManyFieldsErrorFormat","Shown on the Field Selection Dialog when there are too many fields to filter by","Too many fields: {0}","Desteklenmeyen sayıda alan: {0}",""
"Strings.resx","TypeText","Shown in the title bar of quick peek windows for image previews","Type","Format",""
"Strings.resx","UnsupportedFieldCountTextFormat","Shown in the field selection dialog to indicate how many fields are unsupported by ParquetViewer","Unsupported: {0}","Desteklenmeyen: {0}",""
"QuickPeekForm.resx","$this.Text",,"Quick Peek","Hızlı Önizleme",""
"QuickPeekForm.resx","copyToClipboardToolStripMenuItem.Text",,"Copy to clipboard","Panoya kopyala",""
"QuickPeekForm.resx","saveImageToFileButton.Text",,"Save as PNG","PNG olarak Kaydet",""
"QuickPeekForm.resx","takeMeBackLinkLabel.Text",,"<<< back","<<< geri",""

1 File Key Comment EnglishValue TurkishValue NewLanguageValue
59 MainForm.resx newToolStripMenuItem.Text &New Yeni
60 MainForm.resx openFolderToolStripMenuItem.Text &Open Folder Klasör Aç
61 MainForm.resx openFolderToolStripMenuItem.ToolTipText All parquet files in the folder must have the same schema Klasördeki tüm parquet dosyaları aynı veri şemasına sahip olmalıdır
62 MainForm.resx openQueryEditorToolToolStripMenuItem.Text Query Editor (Beta) Sorgu Editörü (Beta)
63 MainForm.resx openToolStripMenuItem.Text &Open File Dosya Aç
64 MainForm.resx outOfStatusBarLabel.Text Out of: Toplam:
65 MainForm.resx recordsTextStatusBarLabel.Text Results Sonuç
77 MetadataViewer.resx $this.Text Parquet Metadata Viewer Parquet Metadata Önizleyicisi
78 MetadataViewer.resx closeButton.Text Close Kapat
79 MetadataViewer.resx loadingTab.Text Loading... Yükleniyor...
80 QueryEditor.resx $this.Text ParquetViewer - Query Editor (Powered by DuckDB) ParquetViewer - Sorgu Editörü (DuckDB Desteğiyle)
81 QueryEditor.resx copyTextMenuItem.Text Copy Kopyala
82 QueryEditor.resx executeQueryButton.Text Execute İşle
83 QueryEditor.resx pasteTextMenuItem.Text Paste Yapıştır
84 QueryEditor.resx queryExecutionStatusLabel.Text Running: İşleniyor:
85 QueryEditor.resx querySyntaxDocsButton.Text Query Syntax Sorgu Söz Dizimi
86 QueryEditor.resx toolStripStatusLabel1.Text Showing: Gösterilen:
87 QueryEditor.resx toolStripStatusLabel2.Text Results Sonuç
88 QueryEditor.resx zoomPercentageDropDown.Text Query Zoom: 100% Sorgu Zumu: 100%
89 QuickPeekForm.resx $this.Text Quick Peek Hızlı Önizleme
90 QuickPeekForm.resx copyToClipboardToolStripMenuItem.Text Copy to clipboard Panoya kopyala
91 QuickPeekForm.resx saveImageToFileButton.Text Save as PNG PNG olarak Kaydet
92 QuickPeekForm.resx takeMeBackLinkLabel.Text <<< back <<< geri
93 Errors.resx CopyAsWhereTooLargeErrorMessage Shown when the user right-click's on too many cells and selects the Copy as WHERE... option The selected data is too large. Please select less cells. Çok fazla veri seçili. Lütfen daha az hücre seçin.
94 Errors.resx CopyAsWhereTooLargeErrorTitle Shown when the user right-click's on too many cells and selects the Copy as WHERE... option Copy to clipboard failed Panoya kopyalama başarısız oldu
95 Errors.resx CopyErrorMessageText Shown in the messagebox for unhandled exceptions to teach users how to copy the error text (CTRL+C to copy) (Kopyalamak için CTRL+C)
211
212
213
214
215
216
282
283
284

View file

@ -20,14 +20,14 @@ jobs:
skip-publish: ${{ steps.check-tag.outputs.exists }}
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
sparse-checkout: |
.github
src
- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@v4.0.1
with:
dotnet-version: '8.0.x'
@ -41,7 +41,7 @@ jobs:
run: dotnet test src/ParquetViewer.sln --no-build --logger trx
- name: Test Report
uses: bibipkins/dotnet-test-reporter@v1.6.1
uses: bibipkins/dotnet-test-reporter@v1.4.1
if: github.repository == 'mukunku/ParquetViewer'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -56,7 +56,7 @@ jobs:
release_version: ${{ steps.release-version.outputs.release_version }}
should_publish: ${{ steps.should-publish.outputs.should_publish }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
sparse-checkout: |
src/ParquetViewer/Properties/AssemblyInfo.cs
@ -72,7 +72,7 @@ jobs:
Write-Host "Checking version $versionMatch"
- name: Is there a finalized release already
uses: mukunku/release-exists-action@v1.1.0
uses: mukunku/release-exists-action@v1.0.0
id: check-release
with:
tag: 'v${{ steps.release-version.outputs.release_version }}'
@ -90,7 +90,7 @@ jobs:
PR_NUMBER: ${{ github.event.number }}
VERSION_NUMBER: ${{ needs.checkPublish.outputs.release_version }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
sparse-checkout: |
.github
@ -108,10 +108,12 @@ jobs:
search-text: 'private const string AMPLITUDE_API_KEY = "";'
replacement-text: 'private const string AMPLITUDE_API_KEY = "${{ secrets.AMPLITUDE_API_KEY }}";'
- name: Build & Publish Regular Release
run: |
dotnet publish src/ParquetViewer/ParquetViewer.csproj -c Release -f net10.0-windows --nologo -o publish -r win-x64 --no-self-contained
Get-Item "./publish/ParquetViewer.exe" | Select-Object Name, Length
# With DuckDB, the regular release is close to 40MB which defeats the purpose of having this version of the release.
# Starting with v4.0.0 we're switching to only publishing the self-contained version.
#- name: Build & Publish Regular Release
# run: |
# dotnet publish src/ParquetViewer/ParquetViewer.csproj -c Release -f net10.0-windows --nologo -o publish -r win-x64 --no-self-contained
# Get-Item "./publish/ParquetViewer.exe" | Select-Object Name, Length
- name: Build & Publish SelfContained Release
run: |
@ -120,25 +122,25 @@ jobs:
- name: Prepare executables for upload
run: |
Move-Item -Path "publish/ParquetViewer.exe" -Destination "./ParquetViewer.exe"
Move-Item -Path "publish_selfcontained/ParquetViewer.exe" -Destination "./ParquetViewer_SelfContained.exe"
#Move-Item -Path "publish/ParquetViewer.exe" -Destination "./ParquetViewer.exe"
Move-Item -Path "publish_selfcontained/ParquetViewer.exe" -Destination "./ParquetViewer.exe"
- name: Upload unsigned artifact for signing
id: upload-unsigned-artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
path: |
ParquetViewer.exe
ParquetViewer_SelfContained.exe
#ParquetViewer_SelfContained.exe
- name: Remove unsigned exe's for safety
run: |
Remove-Item -Path "ParquetViewer.exe"
Remove-Item -Path "ParquetViewer_SelfContained.exe"
#Remove-Item -Path "ParquetViewer_SelfContained.exe"
# Documentation: https://about.signpath.io/documentation/trusted-build-systems/github
- name: Submit signing request to SignPath.io
uses: signpath/github-action-submit-signing-request@v2
uses: signpath/github-action-submit-signing-request@v1.1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '5ceccea7-c3e7-4165-8c2e-adab8679db20'
@ -150,7 +152,7 @@ jobs:
- uses: ncipollo/release-action@v1
with:
artifacts: "signed-package/ParquetViewer.exe,signed-package/ParquetViewer_SelfContained.exe"
artifacts: "signed-package/ParquetViewer.exe" #",signed-package/ParquetViewer_SelfContained.exe"
body: "PR: #${{ env.PR_NUMBER }}"
allowUpdates: ${{ env.BRANCH_NAME != 'main' }}
omitBodyDuringUpdate: true

View file

@ -26,7 +26,7 @@ jobs:
- name: Run PowerShell script
shell: pwsh
run: |
# Find all .resx files for Turkish (tr) as that is our source of truth
# Find all .resx files for Turkish (tr)
$turkishResxFiles = Get-ChildItem -Path . -Recurse -Filter "*.tr.resx"
# Array to hold all combined translation entries

View file

@ -13,7 +13,6 @@ Some key features:
* Run simple sql queries on parquet data
* Open single or partitioned files
* Generate SQL schema from parquet files
* Easily preview & export image and audio data
# Download
Releases can be found here: https://github.com/mukunku/ParquetViewer/releases

View file

@ -10,9 +10,9 @@
<PackageVersion Include="MiniExcel" Version="2.0.0-preview.2" />
<PackageVersion Include="MSTest.TestAdapter" Version="4.0.2" />
<PackageVersion Include="MSTest.TestFramework" Version="4.0.2" />
<PackageVersion Include="NAudio" Version="2.3.0" />
<PackageVersion Include="NAudio.WinForms" Version="2.3.0" />
<PackageVersion Include="Parquet.Net" Version="5.6.0-pre.3" />
<PackageVersion Include="NAudio" Version="2.2.1" />
<PackageVersion Include="NAudio.WinForms" Version="2.2.1" />
<PackageVersion Include="Parquet.Net" Version="5.4.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
</ItemGroup>

View file

@ -74,7 +74,7 @@ namespace ParquetViewer.Engine.DuckDB
"FLOAT" or "REAL" => (DuckDBType.Float, typeof(float)),
"BLOB" => (DuckDBType.Blob, typeof(ByteArrayValue)),
"DATE" => (DuckDBType.Date, typeof(DateOnly)),
"TIME" => (DuckDBType.Time, typeof(TimeOnly)),
"TIME" => (DuckDBType.Time, typeof(TimeSpan)),
"INTERVAL" => (DuckDBType.Interval, typeof(TimeSpan)),
"UUID" => (DuckDBType.Uuid, typeof(Guid)),
_ => throw new ArgumentOutOfRangeException(nameof(duckDBTypeName), $"Unsupported DuckDB type: {duckDBTypeName}({columnTypeName})")

View file

@ -24,7 +24,7 @@ namespace ParquetViewer.Engine.DuckDB
public IParquetMetadata Metadata => this._metadatas.First();
private readonly List<DuckDBField> _fields;
private List<DuckDBField> _fields;
private static int GetFieldsHashCode(List<DuckDBField> fields)
{
@ -134,7 +134,7 @@ namespace ParquetViewer.Engine.DuckDB
var fieldsHashCode = GetFieldsHashCode(fileFields);
if (!fileGroups.ContainsKey(fieldsHashCode))
{
fileGroups.Add(fieldsHashCode, []);
fileGroups.Add(fieldsHashCode, new List<DuckDBHandle>());
}
fileGroups[fieldsHashCode].Add(db);

View file

@ -9,7 +9,6 @@ namespace ParquetViewer.Engine.ParquetNET
{
public partial class ParquetEngine : IParquetEngine, IDisposable
{
private static readonly ParquetOptions _defaultParquetOptions = new () { UseDateOnlyTypeForDates = true, UseTimeOnlyTypeForTimeMicros = true, UseTimeOnlyTypeForTimeMillis = true };
private readonly ParquetReader[] _parquetFiles;
private long? _recordCount;
@ -96,7 +95,7 @@ namespace ParquetViewer.Engine.ParquetNET
try
{
var parquetReader = await ParquetReader.CreateAsync(parquetFilePath, _defaultParquetOptions, cancellationToken);
var parquetReader = await ParquetReader.CreateAsync(parquetFilePath, new() { UseDateOnlyTypeForDates = true }, cancellationToken);
return new ParquetEngine(parquetFilePath, parquetReader);
}
catch (Exception ex)
@ -120,7 +119,7 @@ namespace ParquetViewer.Engine.ParquetNET
try
{
var parquetReader = await ParquetReader.CreateAsync(file, _defaultParquetOptions, cancellationToken);
var parquetReader = await ParquetReader.CreateAsync(file, new() { UseDateOnlyTypeForDates = true }, cancellationToken);
if (!fileGroups.ContainsKey(parquetReader.Schema))
{
fileGroups.Add(parquetReader.Schema, new List<ParquetReader>());

View file

@ -125,7 +125,7 @@ namespace ParquetViewer.Engine
}
jsonWriter.WriteEndArray();
}
else if (value is IByteArrayValue byteArray /*&& truncateForDisplay //should we use the entire byte array if
else if (value is IByteArrayValue byteArray /*&& truncateForDisplay //should use the entire byte array if
* we're not truncating for display? Seems kind of unreasonable
* for users to rely on binary data within a Struct value preview.*/)
{
@ -149,14 +149,6 @@ namespace ParquetViewer.Engine
else
jsonWriter.WriteStringValue(dateOnly.ToString());
}
else if (value is TimeOnly timeOnly)
{
//Write time as string
if (ParquetEngineSettings.TimeOnlyDisplayFormat is not null)
jsonWriter.WriteStringValue(timeOnly.ToString(ParquetEngineSettings.TimeOnlyDisplayFormat));
else
jsonWriter.WriteStringValue(timeOnly.ToString());
}
else
{
//Everything else just try to write it as string

View file

@ -13,6 +13,5 @@ namespace ParquetViewer.Engine
/// <see cref="IStructValue"/>, and <see cref="IMapValue"/> types to string.</remarks>
public static string? DateDisplayFormat { get; set; }
public static string? DateOnlyDisplayFormat { get; set; }
public static string? TimeOnlyDisplayFormat { get; set; }
}
}

View file

@ -122,8 +122,6 @@ namespace ParquetViewer.Engine
key = dt.ToString(ParquetEngineSettings.DateDisplayFormat);
else if (map.Key is DateOnly dateOnly && ParquetEngineSettings.DateOnlyDisplayFormat is not null)
key = dateOnly.ToString(ParquetEngineSettings.DateOnlyDisplayFormat);
else if (map.Key is TimeOnly timeOnly && ParquetEngineSettings.TimeOnlyDisplayFormat is not null)
key = timeOnly.ToString(ParquetEngineSettings.TimeOnlyDisplayFormat);
else
key = map.Key?.ToString() ?? string.Empty;
@ -132,8 +130,6 @@ namespace ParquetViewer.Engine
value = dt2.ToString(ParquetEngineSettings.DateDisplayFormat);
else if (map.Value is DateOnly dateOnly && ParquetEngineSettings.DateOnlyDisplayFormat is not null)
value = dateOnly.ToString(ParquetEngineSettings.DateOnlyDisplayFormat);
else if (map.Value is TimeOnly timeOnly && ParquetEngineSettings.TimeOnlyDisplayFormat is not null)
value = timeOnly.ToString(ParquetEngineSettings.TimeOnlyDisplayFormat);
else
value = map.Value?.ToString() ?? string.Empty;

View file

@ -44,7 +44,6 @@ namespace ParquetViewer.Tests
//Set a consistent date format for all tests
ParquetEngineSettings.DateDisplayFormat = "yyyy-MM-dd HH:mm:ss";
ParquetEngineSettings.DateOnlyDisplayFormat = "yyyy-MM-dd";
ParquetEngineSettings.TimeOnlyDisplayFormat = "HH:mm:ss";
this._useDuckDBEngine = useDuckDBEngine;
this._canHandleNullComplexTypes = canHandleNullComplexTypes;
@ -715,18 +714,5 @@ namespace ParquetViewer.Tests
Assert.IsNull(lastColumn.Statistics.IsMinValueExact);
Assert.IsNull(lastColumn.Statistics.IsMinValueExact);
}
[SkippableTestMethod]
public async Task DATETTIME_ONLY_TYPE_PYARROW_V22()
{
using var parquetEngine = await OpenFileOrFolderAsync("Data/TIME_ONLY_TYPE_PYARROW_V22.parquet", default);
Assert.AreEqual(4626, parquetEngine.RecordCount);
Assert.HasCount(2, parquetEngine.Fields);
var dataTable = (await parquetEngine.ReadRowsAsync(parquetEngine.Fields, 0, int.MaxValue, default))(false);
Assert.AreEqual(new DateOnly(2024, 1, 1), dataTable.Rows[0][0]);
Assert.AreEqual(new TimeOnly(215720000000), dataTable.Rows[0][1]);
}
}
}

View file

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.1.11312.151
VisualStudioVersion = 18.1.11312.151 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParquetViewer", "ParquetViewer\ParquetViewer.csproj", "{6019FC1B-3610-4682-BF96-8345C95CB7EC}"
EndProject
@ -16,8 +16,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F5D39637-1812-4802-8DB3-254CBBE5C313}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
..\.github\workflows\build-test-publish.yaml = ..\.github\workflows\build-test-publish.yaml
..\.github\workflows\generate-translations-template.yaml = ..\.github\workflows\generate-translations-template.yaml
EndProjectSection
EndProject
Global
@ -27,18 +25,18 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release_SelfContained|Any CPU.ActiveCfg = Release_SelfContained|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release_SelfContained|Any CPU.Build.0 = Release_SelfContained|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release|Any CPU.Build.0 = Release|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Release_SelfContained|Any CPU.ActiveCfg = Release|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Release_SelfContained|Any CPU.Build.0 = Release|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77900356-25F3-4A24-B638-845C784C1175}.Release|Any CPU.Build.0 = Release|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release_SelfContained|Any CPU.ActiveCfg = Release_SelfContained|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release_SelfContained|Any CPU.Build.0 = Release_SelfContained|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6019FC1B-3610-4682-BF96-8345C95CB7EC}.Release|Any CPU.Build.0 = Release|Any CPU
{16D10BC9-08BF-4248-8975-1B54C42EB2C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16D10BC9-08BF-4248-8975-1B54C42EB2C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16D10BC9-08BF-4248-8975-1B54C42EB2C2}.Release_SelfContained|Any CPU.ActiveCfg = Release_SelfContained|Any CPU

View file

@ -126,6 +126,7 @@ namespace ParquetViewer.Analytics
UserGuide,
DragDrop,
LoadAllRows,
QueryEditor,
}
}

View file

@ -54,7 +54,6 @@ namespace ParquetViewer.Controls
private DataGridViewCellStyle? hyperlinkCellStyleCache;
private bool isLeftClickButtonDown = false;
private ContextMenuStrip? _contextMenu = null;
private ContextMenuStrip? _headerContextMenu = null;
private static readonly Regex _validColumnNameRegex = new Regex("^[a-zA-Z0-9_]+$");
//We keep track of format overrides with the column name so we can keep formatting the same if the user adds/removes fields from the same file
@ -82,6 +81,7 @@ namespace ParquetViewer.Controls
this.clickableColumnIndexes.Clear();
base.OnDataSourceChanged(e); //This runs OnColumnAdded() for all columns before continuing.
UpdateDateFormats();
SetColumnCellStyles();
AutoSizeColumns();
}
@ -120,21 +120,13 @@ namespace ParquetViewer.Controls
}
}
}
else
{
//Reset any changed stylings
column.DefaultCellStyle = new DataGridViewCellStyle();
}
}
UpdateDateFormats();
}
public void UpdateDateFormats()
{
string dateFormat = AppSettings.DateTimeDisplayFormat.GetDateFormat();
string dateOnlyFormat = AppSettings.DateTimeDisplayFormat.GetDateOnlyFormat();
string timeOnlyFormat = AppSettings.DateTimeDisplayFormat.GetTimeOnlyFormat();
foreach (DataGridViewColumn column in this.Columns)
{
@ -142,14 +134,11 @@ namespace ParquetViewer.Controls
column.DefaultCellStyle.Format = dateFormat;
else if (column.ValueType == typeof(DateOnly))
column.DefaultCellStyle.Format = dateOnlyFormat;
else if (column.ValueType == typeof(TimeOnly))
column.DefaultCellStyle.Format = timeOnlyFormat;
}
//Need to tell the parquet engine how to render date values
ParquetEngineSettings.DateDisplayFormat = dateFormat;
ParquetEngineSettings.DateOnlyDisplayFormat = dateOnlyFormat;
ParquetEngineSettings.TimeOnlyDisplayFormat = timeOnlyFormat;
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
@ -428,8 +417,7 @@ namespace ParquetViewer.Controls
this.ClearSelection();
this.FirstDisplayedScrollingRowIndex = cellToReturnTo.RowIndex;
if (!this.Columns[tag.SourceColumnIndex].Frozen)
this.FirstDisplayedScrollingColumnIndex = tag.SourceColumnIndex;
this.FirstDisplayedScrollingColumnIndex = tag.SourceColumnIndex;
this[cellToReturnTo.ColumnIndex, cellToReturnTo.RowIndex].Selected = true;
this.CurrentCell = cellToReturnTo;
this.Focus();
@ -611,23 +599,14 @@ namespace ParquetViewer.Controls
protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.Cursor = Cursors.WaitCursor;
this.Cursor = Cursors.WaitCursor;
try
{
base.OnColumnHeaderMouseClick(e); //This will trigger the sort operation and the OnSorted event if it's a left-click
if (e.Button == MouseButtons.Right)
{
this._headerContextMenu?.Dispose();
this._headerContextMenu = new ContextMenuStrip();
AddFrozenOption(this._headerContextMenu.Items, e.ColumnIndex);
AddDisplayFormatOptions(this._headerContextMenu.Items, e.ColumnIndex);
if (this._headerContextMenu.Items.Count > 0)
this._headerContextMenu.Show(Cursor.Position);
ShowDisplayFormatOptions(e.ColumnIndex);
}
}
finally
@ -735,7 +714,7 @@ namespace ParquetViewer.Controls
//We can just measure a few without going through all of them.
colStringCollection = nonNullColumnValues
.Select(row => row.Field<DateTime>(i).ToString(AppSettings.DateTimeDisplayFormat.GetDateFormat()))
.Take(25);
.Take(50);
}
else if (gridTable.Columns[i].DataType == typeof(DateOnly))
{
@ -745,14 +724,6 @@ namespace ParquetViewer.Controls
.Select(row => row.Field<DateOnly>(i).ToString(AppSettings.DateTimeDisplayFormat.GetDateOnlyFormat()))
.Take(10);
}
else if (gridTable.Columns[i].DataType == typeof(TimeOnly))
{
//All date only's will probably have the same string length so no need to go through all values.
//We can just measure a few without going through all of them.
colStringCollection = nonNullColumnValues
.Select(row => row.Field<TimeOnly>(i).ToString(AppSettings.DateTimeDisplayFormat.GetTimeOnlyFormat()))
.Take(25);
}
else if (gridTable.Columns[i].DataType.ImplementsInterface<IStructValue>())
{
colStringCollection = nonNullColumnValues
@ -904,6 +875,9 @@ namespace ParquetViewer.Controls
this.DefaultCellStyle.ForeColor = this.GridTheme.TextColor;
this.DefaultCellStyle.SelectionBackColor = this.GridTheme.SelectionBackColor;
this.ColumnHeadersDefaultCellStyle.BackColor = this.GridTheme.ColumnHeaderColor;
this.ColumnHeadersDefaultCellStyle.ForeColor = this.GridTheme.TextColor;
this.RowHeadersDefaultCellStyle.BackColor = this.GridTheme.RowHeaderColor;
this.RowHeadersDefaultCellStyle.ForeColor = this.GridTheme.TextColor;
this.RowHeadersDefaultCellStyle.SelectionBackColor = this.GridTheme.SelectionBackColor;
@ -923,7 +897,6 @@ namespace ParquetViewer.Controls
WrapMode = DataGridViewTriState.True
};
StyleFrozenColumns();
SetColumnCellStyles();
}
@ -1083,13 +1056,12 @@ namespace ParquetViewer.Controls
return queryBuilder.ToString();
}
private void AddDisplayFormatOptions(ToolStripItemCollection contextMenu, int columnIndex)
private void ShowDisplayFormatOptions(int columnIndex)
{
//If this is a byte array column, show available formatting options
if (this.Columns[columnIndex].ValueType.ImplementsInterface<IByteArrayValue>()
&& this.Columns[columnIndex].CellTemplate?.GetType() != typeof(AudioPlayerDataGridViewCell))
{
AddSeperatorIfNeeded();
const int RECORDS_TO_INTERSECT_COUNT = 8;
//Find a few different non-null values and find the common display formats that all of them support.
@ -1114,6 +1086,7 @@ namespace ParquetViewer.Controls
possibleDisplayFormats = [default];
}
var columnHeaderContextMenu = new ContextMenuStrip();
foreach (var supportedFormat in possibleDisplayFormats)
{
var columnName = this.Columns[columnIndex].Name;
@ -1129,17 +1102,20 @@ namespace ParquetViewer.Controls
this.Refresh(); //Force a re-draw to render updated format
this.AutoSizeColumns(columnIndex); //Re-size the column
};
contextMenu.Add(toolstripMenuItem);
columnHeaderContextMenu.Items.Add(toolstripMenuItem);
if (!byteArrayColumnsWithFormatOverrides.TryGetValue(columnName, out var displayFormat))
displayFormat = default;
toolstripMenuItem.Checked = displayFormat == supportedFormat;
}
columnHeaderContextMenu.Show(Cursor.Position);
}
else if (this.Columns[columnIndex].ValueType == typeof(float) || this.Columns[columnIndex].ValueType == typeof(double))
{
AddSeperatorIfNeeded();
var columnHeaderContextMenu = new ContextMenuStrip();
var columnName = this.Columns[columnIndex].Name;
if (!floatColumnsWithFormatOverrides.TryGetValue(columnName, out var displayFormat))
displayFormat = default;
@ -1158,7 +1134,7 @@ namespace ParquetViewer.Controls
this.Refresh(); //Force a re-draw to render updated format
this.AutoSizeColumns(columnIndex); //Re-size the column
};
contextMenu.Add(scientificNotationMenuItem);
columnHeaderContextMenu.Items.Add(scientificNotationMenuItem);
var decimalNotationMenuItem = new ToolStripMenuItem(Resources.Strings.DecimalFormatting)
{ Checked = displayFormat == FloatDisplayFormat.Decimal };
@ -1174,56 +1150,9 @@ namespace ParquetViewer.Controls
this.Refresh(); //Force a re-draw to render updated format
this.AutoSizeColumns(columnIndex); //Re-size the column
};
contextMenu.Add(decimalNotationMenuItem);
}
columnHeaderContextMenu.Items.Add(decimalNotationMenuItem);
void AddSeperatorIfNeeded()
{
if (contextMenu.Count > 0)
contextMenu.Add(new ToolStripSeparator());
}
}
private void AddFrozenOption(ToolStripItemCollection items, int columnIndex)
{
var column = this.Columns[columnIndex];
//Only show the option to freeze if the horizontal scroll bar is visible or if the column is already frozen
if (!column.Frozen && !this.HorizontalScrollBar.Visible)
return;
var menuItem = new ToolStripMenuItem(Resources.Strings.FrozenColumnText)
{ Checked = column.Frozen };
menuItem.Click += (object? _, EventArgs _) =>
{
column.Frozen = !column.Frozen;
this.StyleFrozenColumns();
};
items.Add(menuItem);
}
private void StyleFrozenColumns()
{
//First reset styles for all column headers
for (var i = 0; i < this.Columns.Count; i++)
{
this.Columns[i].HeaderCell.Style = new DataGridViewCellStyle();
}
//Reset cells
SetColumnCellStyles();
//Now style frozen ones (We need to go by DisplayIndex in case the user re-arranged the columns)
var columnsInOrderByDisplayIndex = this.Columns.AsEnumerable().OrderBy(col => col.DisplayIndex);
foreach (var column in columnsInOrderByDisplayIndex)
{
if (!column.Frozen)
break;
column.DefaultCellStyle.BackColor = this.GridTheme.FrozenCellBackgroundColor;
column.HeaderCell.Style.BackColor = this.GridTheme.FrozenColumnHeaderColor;
columnHeaderContextMenu.Show(Cursor.Position);
}
}
@ -1404,9 +1333,6 @@ namespace ParquetViewer.Controls
//dispose any AudioPlayerDataGridViewCells to free resources and stop ongoing playback.
this.DisposeAudioCells();
this._contextMenu?.Dispose();
this._headerContextMenu?.Dispose();
base.Dispose(disposing);
}

View file

@ -248,7 +248,7 @@ namespace ParquetViewer
AppSettings.AlwaysSelectAllFields = false;
this.NewSelectedFields.Clear();
if (this.allFieldsRadioButton.Checked)
if (this.allFieldsRadioButton.Checked || (this.fieldsPanel.Controls.Find(SelectAllCheckboxName, true).FirstOrDefault() as CheckBox)?.Checked == true)
{
this.NewSelectedFields.AddRange(this.AvailableFields);
}

View file

@ -15,7 +15,6 @@ namespace ParquetViewer.Helpers
{ typeof(bool), "BIT {1}NULL" },
{ typeof(char), "CHAR {1}NULL" },
{ typeof(DateTime), "DATETIME {1}NULL" },
{ typeof(DateOnly), "DATE {1}NULL" },
{ typeof(double), "FLOAT {1}NULL" },
{ typeof(uint), "INT {1}NULL" },
{ typeof(int), "INT {1}NULL" },
@ -28,7 +27,6 @@ namespace ParquetViewer.Helpers
{ typeof(sbyte), "TINYINT {1}NULL" },
{ typeof(string), "NVARCHAR({0}) {1}NULL" },
{ typeof(TimeSpan), "INT {1}NULL" },
{ typeof(TimeOnly), "INT {1}NULL" },
{ typeof(byte[]), "VARBINARY {1}NULL" },
{ typeof(IListValue), "sql_variant {1}NULL /*LIST*/" },
{ typeof(IMapValue), "sql_variant {1}NULL /*MAP*/" },

View file

@ -1,4 +1,5 @@
using Microsoft.Win32;
using ParquetViewer.Engine.ParquetNET.Types;
using ParquetViewer.Engine.Types;
using System;
using System.Collections.Generic;
@ -6,6 +7,7 @@ using System.ComponentModel;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
@ -16,10 +18,8 @@ namespace ParquetViewer.Helpers
{
private const string DefaultDateTimeFormat = "g";
private const string DefaultDateOnlyFormat = "d";
private const string DefaultTimeOnlyFormat = "T";
public const string ISO8601DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFF";
public const string ISO8601DateOnlyFormat = "yyyy-MM-dd";
public const string ISO8601TimeOnlyFormat = "HH:mm:ss.FFFFFFF";
/// <summary>
/// Returns a list of all column names within a given datatable
@ -54,16 +54,7 @@ namespace ParquetViewer.Helpers
DateFormat.ISO8601 => ISO8601DateOnlyFormat,
DateFormat.Default => DefaultDateOnlyFormat,
DateFormat.Custom => AppSettings.CustomDateFormat is not null ?
UtilityMethods.StripTimeComponentsFromDateTimeFormat(AppSettings.CustomDateFormat) : DefaultDateOnlyFormat,
_ => string.Empty
};
public static string GetTimeOnlyFormat(this DateFormat dateFormat) => dateFormat switch
{
DateFormat.ISO8601 => ISO8601TimeOnlyFormat,
DateFormat.Default => DefaultTimeOnlyFormat,
DateFormat.Custom => AppSettings.CustomDateFormat is not null ?
UtilityMethods.StripDateComponentsFromDateTimeFormat(AppSettings.CustomDateFormat) : DefaultTimeOnlyFormat,
UtilityMethods.StripTimeComponentsFromDateFormat(AppSettings.CustomDateFormat) : DefaultDateOnlyFormat,
_ => string.Empty
};
@ -99,14 +90,6 @@ namespace ParquetViewer.Helpers
}
}
public static IEnumerable<DataGridViewColumn> AsEnumerable(this DataGridViewColumnCollection columns)
{
foreach (DataGridViewColumn column in columns)
{
yield return column;
}
}
/// <summary>
/// Returns true if the type is a "simple" type. Basically anything that isn't a class, struct or array.
/// </summary>

View file

@ -19,8 +19,6 @@ namespace ParquetViewer.Helpers
public Color SelectionBackColor { get; }
public Color FormBackgroundColor { get; }
public Color DisabledTextColor { get; }
public Color FrozenColumnHeaderColor { get; }
public Color FrozenCellBackgroundColor { get; }
private readonly Func<Theme, ToolStripProfessionalRenderer>? _toolStripRendererProvider = null;
public bool HasToolStripRendererProvider => _toolStripRendererProvider is not null;
@ -43,14 +41,13 @@ namespace ParquetViewer.Helpers
Color formBackgroundColor,
Func<Theme, ToolStripProfessionalRenderer>? toolStripRendererProvider,
Color activeHyperlinkColor,
Color disabledTextColor,
Color frozenColumnHeaderColor,
Color frozenCellBackgroundColor)
Color disabledTextColor)
{
this.CellBackgroundColor = cellBackgroundColor;
this.TextColor = textColor;
this.AlternateRowsCellBackgroundColor = alternateRowsCellBackgroundColor;
this.ColumnHeaderColor = columnHeaderColor;
this.ColumnHeaderColor = columnHeaderColor;
this.RowHeaderColor = rowHeaderColor;
this.RowHeaderBorderStyle = rowHeaderBorderStyle;
this.GridBackgroundColor = gridBackgroundColor;
@ -62,8 +59,6 @@ namespace ParquetViewer.Helpers
this._toolStripRendererProvider = toolStripRendererProvider;
this.ActiveHyperlinkColor = activeHyperlinkColor;
this.DisabledTextColor = disabledTextColor;
this.FrozenColumnHeaderColor = frozenColumnHeaderColor;
this.FrozenCellBackgroundColor = frozenCellBackgroundColor;
}
public static Theme DarkModeTheme => new(
@ -81,9 +76,7 @@ namespace ParquetViewer.Helpers
Color.FromArgb(44, 44, 44),
(theme) => { return new DarkModeToolStripRenderer(theme); },
Color.LightGray,
Color.DarkGray,
Color.FromArgb(33, 37, 63),
Color.FromArgb(40, 44, 48)
Color.DarkGray
);
public static Theme LightModeTheme => new(
@ -101,9 +94,7 @@ namespace ParquetViewer.Helpers
SystemColors.Control,
null,
Color.Red,
Color.DarkGray,
SystemColors.InactiveCaption,
SystemColors.InactiveBorder
Color.DarkGray
);
public bool Equals(Theme other) => this.GetHashCode() == other.GetHashCode(); //Not perfect but good enough

View file

@ -100,11 +100,11 @@ namespace ParquetViewer.Helpers
}
/// <summary>
/// Best effort attempt at stripping time components from a datetime format string.
/// Best effort attempt at stripping time components from a date format string.
/// </summary>
/// <param name="dateFormat">Date format with potential time components</param>
/// <returns>Date format with no time components</returns>
public static string StripTimeComponentsFromDateTimeFormat(string dateFormat)
public static string StripTimeComponentsFromDateFormat(string dateFormat)
{
var timeComponents = new string[] { "H", "h", "m", "s", "f", "F", "t", "z", "K" };
foreach (var component in timeComponents)
@ -115,22 +115,5 @@ namespace ParquetViewer.Helpers
dateFormat = dateFormat.TrimEnd('/', '-', '.', ' ', ',', '_');
return dateFormat.Trim();
}
/// <summary>
/// Best effort attempt at stripping date components from a datetime format string.
/// </summary>
/// <param name="dateFormat">Date format with potential date components</param>
/// <returns>Time format with no date components</returns>
public static string StripDateComponentsFromDateTimeFormat(string dateFormat)
{
var dateComponents = new string[] { "y", "M", "d", "g" };
foreach (var component in dateComponents)
{
dateFormat = dateFormat.Replace(component, string.Empty);
}
dateFormat = dateFormat.Replace(" ", " ");
dateFormat = dateFormat.TrimStart('/', '-', '.', ' ', ',', '_');
return dateFormat.Trim();
}
}
}

View file

@ -35,7 +35,7 @@ namespace ParquetViewer
{
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle2 = new DataGridViewCellStyle();
mainTableLayoutPanel = new TableLayoutPanel();
recordsToLabel = new Label();
recordCountTextBox = new DelayedOnChangedTextBox();
@ -68,6 +68,7 @@ namespace ParquetViewer
toolsToolStripMenuItem = new ToolStripMenuItem();
getSQLCreateTableScriptToolStripMenuItem = new ToolStripMenuItem();
metadataViewerToolStripMenuItem = new ToolStripMenuItem();
openQueryEditorToolToolStripMenuItem = new ToolStripMenuItem();
helpToolStripMenuItem = new ToolStripMenuItem();
userGuideToolStripMenuItem = new ToolStripMenuItem();
shareAnonymousUsageDataToolStripMenuItem = new ToolStripMenuItem();
@ -107,17 +108,20 @@ namespace ParquetViewer
mainTableLayoutPanel.Controls.Add(mainGridView, 0, 1);
mainTableLayoutPanel.Controls.Add(loadAllRowsButton, 10, 0);
mainTableLayoutPanel.Name = "mainTableLayoutPanel";
loadAllRowsButtonTooltip.SetToolTip(mainTableLayoutPanel, resources.GetString("mainTableLayoutPanel.ToolTip"));
//
// recordsToLabel
//
resources.ApplyResources(recordsToLabel, "recordsToLabel");
recordsToLabel.Name = "recordsToLabel";
loadAllRowsButtonTooltip.SetToolTip(recordsToLabel, resources.GetString("recordsToLabel.ToolTip"));
//
// recordCountTextBox
//
resources.ApplyResources(recordCountTextBox, "recordCountTextBox");
recordCountTextBox.DelayedTextChangedTimeout = 1000;
recordCountTextBox.Name = "recordCountTextBox";
loadAllRowsButtonTooltip.SetToolTip(recordCountTextBox, resources.GetString("recordCountTextBox.ToolTip"));
recordCountTextBox.DelayedTextChanged += recordsToTextBox_TextChanged;
recordCountTextBox.KeyPress += recordsToTextBox_KeyPress;
//
@ -125,12 +129,14 @@ namespace ParquetViewer
//
resources.ApplyResources(showRecordsFromLabel, "showRecordsFromLabel");
showRecordsFromLabel.Name = "showRecordsFromLabel";
loadAllRowsButtonTooltip.SetToolTip(showRecordsFromLabel, resources.GetString("showRecordsFromLabel.ToolTip"));
//
// offsetTextBox
//
resources.ApplyResources(offsetTextBox, "offsetTextBox");
offsetTextBox.DelayedTextChangedTimeout = 1000;
offsetTextBox.Name = "offsetTextBox";
loadAllRowsButtonTooltip.SetToolTip(offsetTextBox, resources.GetString("offsetTextBox.ToolTip"));
offsetTextBox.DelayedTextChanged += offsetTextBox_TextChanged;
offsetTextBox.KeyPress += offsetTextBox_KeyPress;
//
@ -140,6 +146,7 @@ namespace ParquetViewer
runQueryButton.ForeColor = System.Drawing.Color.DarkRed;
runQueryButton.Image = Resources.Icons.exclamation_icon;
runQueryButton.Name = "runQueryButton";
loadAllRowsButtonTooltip.SetToolTip(runQueryButton, resources.GetString("runQueryButton.ToolTip"));
runQueryButton.UseVisualStyleBackColor = true;
runQueryButton.Click += runQueryButton_Click;
//
@ -150,6 +157,7 @@ namespace ParquetViewer
searchFilterLabel.LinkColor = System.Drawing.Color.Navy;
searchFilterLabel.Name = "searchFilterLabel";
searchFilterLabel.TabStop = true;
loadAllRowsButtonTooltip.SetToolTip(searchFilterLabel, resources.GetString("searchFilterLabel.ToolTip"));
searchFilterLabel.LinkClicked += searchFilterLabel_Click;
//
// searchFilterTextBox
@ -157,6 +165,7 @@ namespace ParquetViewer
resources.ApplyResources(searchFilterTextBox, "searchFilterTextBox");
mainTableLayoutPanel.SetColumnSpan(searchFilterTextBox, 2);
searchFilterTextBox.Name = "searchFilterTextBox";
loadAllRowsButtonTooltip.SetToolTip(searchFilterTextBox, resources.GetString("searchFilterTextBox.ToolTip"));
searchFilterTextBox.Enter += searchFilterTextBox_Enter;
searchFilterTextBox.KeyPress += searchFilterTextBox_KeyPress;
searchFilterTextBox.Leave += searchFilterTextBox_Leave;
@ -166,37 +175,38 @@ namespace ParquetViewer
resources.ApplyResources(clearFilterButton, "clearFilterButton");
clearFilterButton.ForeColor = System.Drawing.Color.Black;
clearFilterButton.Name = "clearFilterButton";
loadAllRowsButtonTooltip.SetToolTip(clearFilterButton, resources.GetString("clearFilterButton.ToolTip"));
clearFilterButton.UseVisualStyleBackColor = true;
clearFilterButton.Click += clearFilterButton_Click;
//
// mainGridView
//
resources.ApplyResources(mainGridView, "mainGridView");
mainGridView.AllowUserToAddRows = false;
mainGridView.AllowUserToDeleteRows = false;
mainGridView.AllowUserToOrderColumns = true;
resources.ApplyResources(mainGridView, "mainGridView");
mainGridView.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
mainGridView.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.ControlLight;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True;
mainGridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.ControlLight;
dataGridViewCellStyle2.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle2.WrapMode = DataGridViewTriState.True;
mainGridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;
mainGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
mainGridView.ColumnNameEscapeFormat = "[{0}]";
mainTableLayoutPanel.SetColumnSpan(mainGridView, 11);
mainGridView.CopyAsWhereIcon = (System.Drawing.Image)resources.GetObject("mainGridView.CopyAsWhereIcon");
mainGridView.CopyToClipboardIcon = (System.Drawing.Image)resources.GetObject("mainGridView.CopyToClipboardIcon");
mainGridView.DateValueEscapeFormat = "#{0}#";
mainGridView.EnableHeadersVisualStyles = false;
mainGridView.Name = "mainGridView";
mainGridView.ReadOnly = true;
mainTableLayoutPanel.SetRowSpan(mainGridView, 2);
mainGridView.ShowCellToolTips = false;
mainGridView.ShowCopyAsWhereContextMenuItem = true;
loadAllRowsButtonTooltip.SetToolTip(mainGridView, resources.GetString("mainGridView.ToolTip"));
mainGridView.DataBindingComplete += mainGridView_DataBindingComplete;
//
// loadAllRowsButton
@ -218,16 +228,17 @@ namespace ParquetViewer
//
// mainMenuStrip
//
resources.ApplyResources(mainMenuStrip, "mainMenuStrip");
mainMenuStrip.BackColor = System.Drawing.SystemColors.Control;
mainMenuStrip.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, editToolStripMenuItem, toolsToolStripMenuItem, helpToolStripMenuItem });
resources.ApplyResources(mainMenuStrip, "mainMenuStrip");
mainMenuStrip.Name = "mainMenuStrip";
loadAllRowsButtonTooltip.SetToolTip(mainMenuStrip, resources.GetString("mainMenuStrip.ToolTip"));
//
// fileToolStripMenuItem
//
resources.ApplyResources(fileToolStripMenuItem, "fileToolStripMenuItem");
fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { newToolStripMenuItem, openToolStripMenuItem, openFolderToolStripMenuItem, toolStripSeparator, saveAsToolStripMenuItem, toolStripSeparator1, exitToolStripMenuItem });
fileToolStripMenuItem.Name = "fileToolStripMenuItem";
resources.ApplyResources(fileToolStripMenuItem, "fileToolStripMenuItem");
//
// newToolStripMenuItem
//
@ -243,14 +254,14 @@ namespace ParquetViewer
//
// openFolderToolStripMenuItem
//
openFolderToolStripMenuItem.Name = "openFolderToolStripMenuItem";
resources.ApplyResources(openFolderToolStripMenuItem, "openFolderToolStripMenuItem");
openFolderToolStripMenuItem.Name = "openFolderToolStripMenuItem";
openFolderToolStripMenuItem.Click += openFolderToolStripMenuItem_Click;
//
// toolStripSeparator
//
toolStripSeparator.Name = "toolStripSeparator";
resources.ApplyResources(toolStripSeparator, "toolStripSeparator");
toolStripSeparator.Name = "toolStripSeparator";
//
// saveAsToolStripMenuItem
//
@ -260,20 +271,20 @@ namespace ParquetViewer
//
// toolStripSeparator1
//
toolStripSeparator1.Name = "toolStripSeparator1";
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
toolStripSeparator1.Name = "toolStripSeparator1";
//
// exitToolStripMenuItem
//
exitToolStripMenuItem.Name = "exitToolStripMenuItem";
resources.ApplyResources(exitToolStripMenuItem, "exitToolStripMenuItem");
exitToolStripMenuItem.Name = "exitToolStripMenuItem";
exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
//
// editToolStripMenuItem
//
resources.ApplyResources(editToolStripMenuItem, "editToolStripMenuItem");
editToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { changeFieldsMenuStripButton, changeDateFormatToolStripMenuItem, alwaysLoadAllRecordsToolStripMenuItem, darkModeToolStripMenuItem });
editToolStripMenuItem.Name = "editToolStripMenuItem";
resources.ApplyResources(editToolStripMenuItem, "editToolStripMenuItem");
//
// changeFieldsMenuStripButton
//
@ -283,50 +294,50 @@ namespace ParquetViewer
//
// changeDateFormatToolStripMenuItem
//
changeDateFormatToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { defaultToolStripMenuItem, iSO8601ToolStripMenuItem, customDateFormatToolStripMenuItem });
resources.ApplyResources(changeDateFormatToolStripMenuItem, "changeDateFormatToolStripMenuItem");
changeDateFormatToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { defaultToolStripMenuItem, iSO8601ToolStripMenuItem, customDateFormatToolStripMenuItem });
changeDateFormatToolStripMenuItem.Name = "changeDateFormatToolStripMenuItem";
//
// defaultToolStripMenuItem
//
defaultToolStripMenuItem.Name = "defaultToolStripMenuItem";
resources.ApplyResources(defaultToolStripMenuItem, "defaultToolStripMenuItem");
defaultToolStripMenuItem.Name = "defaultToolStripMenuItem";
defaultToolStripMenuItem.Tag = "0";
defaultToolStripMenuItem.Click += DateFormatMenuItem_Click;
//
// iSO8601ToolStripMenuItem
//
iSO8601ToolStripMenuItem.Name = "iSO8601ToolStripMenuItem";
resources.ApplyResources(iSO8601ToolStripMenuItem, "iSO8601ToolStripMenuItem");
iSO8601ToolStripMenuItem.Name = "iSO8601ToolStripMenuItem";
iSO8601ToolStripMenuItem.Tag = "2";
iSO8601ToolStripMenuItem.Click += DateFormatMenuItem_Click;
//
// customDateFormatToolStripMenuItem
//
customDateFormatToolStripMenuItem.Name = "customDateFormatToolStripMenuItem";
resources.ApplyResources(customDateFormatToolStripMenuItem, "customDateFormatToolStripMenuItem");
customDateFormatToolStripMenuItem.Name = "customDateFormatToolStripMenuItem";
customDateFormatToolStripMenuItem.Tag = "6";
customDateFormatToolStripMenuItem.Click += DateFormatMenuItem_Click;
//
// alwaysLoadAllRecordsToolStripMenuItem
//
resources.ApplyResources(alwaysLoadAllRecordsToolStripMenuItem, "alwaysLoadAllRecordsToolStripMenuItem");
alwaysLoadAllRecordsToolStripMenuItem.Checked = true;
alwaysLoadAllRecordsToolStripMenuItem.CheckState = CheckState.Checked;
alwaysLoadAllRecordsToolStripMenuItem.Name = "alwaysLoadAllRecordsToolStripMenuItem";
resources.ApplyResources(alwaysLoadAllRecordsToolStripMenuItem, "alwaysLoadAllRecordsToolStripMenuItem");
alwaysLoadAllRecordsToolStripMenuItem.Click += alwaysLoadAllRecordsToolStripMenuItem_Click;
//
// darkModeToolStripMenuItem
//
darkModeToolStripMenuItem.Name = "darkModeToolStripMenuItem";
resources.ApplyResources(darkModeToolStripMenuItem, "darkModeToolStripMenuItem");
darkModeToolStripMenuItem.Name = "darkModeToolStripMenuItem";
darkModeToolStripMenuItem.Click += darkModeToolStripMenuItem_Click;
//
// toolsToolStripMenuItem
//
toolsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { getSQLCreateTableScriptToolStripMenuItem, metadataViewerToolStripMenuItem });
toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
resources.ApplyResources(toolsToolStripMenuItem, "toolsToolStripMenuItem");
toolsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { getSQLCreateTableScriptToolStripMenuItem, metadataViewerToolStripMenuItem, openQueryEditorToolToolStripMenuItem });
toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
//
// getSQLCreateTableScriptToolStripMenuItem
//
@ -341,57 +352,63 @@ namespace ParquetViewer
metadataViewerToolStripMenuItem.Name = "metadataViewerToolStripMenuItem";
metadataViewerToolStripMenuItem.Click += MetadataViewerToolStripMenuItem_Click;
//
// openQueryEditorToolToolStripMenuItem
//
resources.ApplyResources(openQueryEditorToolToolStripMenuItem, "openQueryEditorToolToolStripMenuItem");
openQueryEditorToolToolStripMenuItem.Name = "openQueryEditorToolToolStripMenuItem";
openQueryEditorToolToolStripMenuItem.Click += openQueryEditorToolToolStripMenuItem_Click;
//
// helpToolStripMenuItem
//
resources.ApplyResources(helpToolStripMenuItem, "helpToolStripMenuItem");
helpToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { userGuideToolStripMenuItem, shareAnonymousUsageDataToolStripMenuItem, languageToolStripMenuItem, aboutToolStripMenuItem });
helpToolStripMenuItem.Name = "helpToolStripMenuItem";
resources.ApplyResources(helpToolStripMenuItem, "helpToolStripMenuItem");
//
// userGuideToolStripMenuItem
//
resources.ApplyResources(userGuideToolStripMenuItem, "userGuideToolStripMenuItem");
userGuideToolStripMenuItem.Image = Resources.Icons.external_link_icon;
userGuideToolStripMenuItem.Name = "userGuideToolStripMenuItem";
resources.ApplyResources(userGuideToolStripMenuItem, "userGuideToolStripMenuItem");
userGuideToolStripMenuItem.Click += userGuideToolStripMenuItem_Click;
//
// shareAnonymousUsageDataToolStripMenuItem
//
shareAnonymousUsageDataToolStripMenuItem.Name = "shareAnonymousUsageDataToolStripMenuItem";
resources.ApplyResources(shareAnonymousUsageDataToolStripMenuItem, "shareAnonymousUsageDataToolStripMenuItem");
shareAnonymousUsageDataToolStripMenuItem.Name = "shareAnonymousUsageDataToolStripMenuItem";
shareAnonymousUsageDataToolStripMenuItem.CheckedChanged += shareAnonymousUsageDataToolStripMenuItem_CheckedChanged;
shareAnonymousUsageDataToolStripMenuItem.Click += shareAnonymousUsageDataToolStripMenuItem_Click;
//
// languageToolStripMenuItem
//
resources.ApplyResources(languageToolStripMenuItem, "languageToolStripMenuItem");
languageToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { englishToolStripMenuItem, turkishToolStripMenuItem });
languageToolStripMenuItem.Image = Resources.Icons.localization_icon;
languageToolStripMenuItem.Name = "languageToolStripMenuItem";
resources.ApplyResources(languageToolStripMenuItem, "languageToolStripMenuItem");
//
// englishToolStripMenuItem
//
englishToolStripMenuItem.Name = "englishToolStripMenuItem";
resources.ApplyResources(englishToolStripMenuItem, "englishToolStripMenuItem");
englishToolStripMenuItem.Name = "englishToolStripMenuItem";
englishToolStripMenuItem.Tag = "en-US";
englishToolStripMenuItem.Click += languageToolStripMenuItem_Click;
//
// turkishToolStripMenuItem
//
turkishToolStripMenuItem.Name = "turkishToolStripMenuItem";
resources.ApplyResources(turkishToolStripMenuItem, "turkishToolStripMenuItem");
turkishToolStripMenuItem.Name = "turkishToolStripMenuItem";
turkishToolStripMenuItem.Tag = "tr-TR";
turkishToolStripMenuItem.Click += languageToolStripMenuItem_Click;
//
// aboutToolStripMenuItem
//
aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
resources.ApplyResources(aboutToolStripMenuItem, "aboutToolStripMenuItem");
aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
aboutToolStripMenuItem.Click += aboutToolStripMenuItem_Click;
//
// showingRecordCountStatusBarLabel
//
showingRecordCountStatusBarLabel.Name = "showingRecordCountStatusBarLabel";
resources.ApplyResources(showingRecordCountStatusBarLabel, "showingRecordCountStatusBarLabel");
showingRecordCountStatusBarLabel.Name = "showingRecordCountStatusBarLabel";
//
// actualShownRecordCountLabel
//
@ -400,19 +417,19 @@ namespace ParquetViewer
//
// recordsTextStatusBarLabel
//
recordsTextStatusBarLabel.Name = "recordsTextStatusBarLabel";
resources.ApplyResources(recordsTextStatusBarLabel, "recordsTextStatusBarLabel");
recordsTextStatusBarLabel.Name = "recordsTextStatusBarLabel";
//
// springStatusBarLabel
//
springStatusBarLabel.Name = "springStatusBarLabel";
resources.ApplyResources(springStatusBarLabel, "springStatusBarLabel");
springStatusBarLabel.Name = "springStatusBarLabel";
springStatusBarLabel.Spring = true;
//
// showingStatusBarLabel
//
showingStatusBarLabel.Name = "showingStatusBarLabel";
resources.ApplyResources(showingStatusBarLabel, "showingStatusBarLabel");
showingStatusBarLabel.Name = "showingStatusBarLabel";
showingStatusBarLabel.Click += showingStatusBarLabel_Click;
//
// recordCountStatusBarLabel
@ -422,8 +439,8 @@ namespace ParquetViewer
//
// outOfStatusBarLabel
//
outOfStatusBarLabel.Name = "outOfStatusBarLabel";
resources.ApplyResources(outOfStatusBarLabel, "outOfStatusBarLabel");
outOfStatusBarLabel.Name = "outOfStatusBarLabel";
//
// totalRowCountStatusBarLabel
//
@ -432,10 +449,11 @@ namespace ParquetViewer
//
// mainStatusStrip
//
mainStatusStrip.Items.AddRange(new ToolStripItem[] { showingRecordCountStatusBarLabel, actualShownRecordCountLabel, recordsTextStatusBarLabel, springStatusBarLabel, showingStatusBarLabel, recordCountStatusBarLabel, outOfStatusBarLabel, totalRowCountStatusBarLabel });
resources.ApplyResources(mainStatusStrip, "mainStatusStrip");
mainStatusStrip.Items.AddRange(new ToolStripItem[] { showingRecordCountStatusBarLabel, actualShownRecordCountLabel, recordsTextStatusBarLabel, springStatusBarLabel, showingStatusBarLabel, recordCountStatusBarLabel, outOfStatusBarLabel, totalRowCountStatusBarLabel });
mainStatusStrip.Name = "mainStatusStrip";
mainStatusStrip.ShowItemToolTips = true;
loadAllRowsButtonTooltip.SetToolTip(mainStatusStrip, resources.GetString("mainStatusStrip.ToolTip"));
//
// exportFileDialog
//
@ -450,8 +468,8 @@ namespace ParquetViewer
//
// MainForm
//
AllowDrop = true;
resources.ApplyResources(this, "$this");
AllowDrop = true;
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(mainStatusStrip);
Controls.Add(mainTableLayoutPanel);
@ -460,6 +478,7 @@ namespace ParquetViewer
KeyPreview = true;
MainMenuStrip = mainMenuStrip;
Name = "MainForm";
loadAllRowsButtonTooltip.SetToolTip(this, resources.GetString("$this.ToolTip"));
Load += MainForm_Load;
DragDrop += MainForm_DragDrop;
DragEnter += MainForm_DragEnter;
@ -529,6 +548,7 @@ namespace ParquetViewer
private ToolStripMenuItem languageToolStripMenuItem;
private ToolStripMenuItem englishToolStripMenuItem;
private ToolStripMenuItem turkishToolStripMenuItem;
private ToolStripMenuItem openQueryEditorToolToolStripMenuItem;
}
}

View file

@ -46,7 +46,7 @@ namespace ParquetViewer
private void recordsToTextBox_TextChanged(object sender, EventArgs? e)
{
var textbox = (TextBox)sender;
if (int.TryParse(textbox.Text, out var recordCount) && recordCount > 0)
if (int.TryParse(textbox.Text, out var recordCount) && recordCount >= 0)
this.CurrentMaxRowCount = recordCount;
else
textbox.Text = this.CurrentMaxRowCount.ToString();
@ -288,5 +288,34 @@ namespace ParquetViewer
AppSettings.UserSelectedCulture = newCultureInfo;
UtilityMethods.RestartApplication();
}
private QueryEditor? _openQueryEditor = null;
private string? _queryEditorSavedQueryText = null;
private void openQueryEditorToolToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this._openQueryEditor == null || this._openQueryEditor.IsDisposed)
{
this._openQueryEditor = new QueryEditor(this.SelectedFields, this.OpenFileOrFolderPath, this.CurrentOffset, this.CurrentMaxRowCount);
this._openQueryEditor.FormClosed += (s, args) =>
{
//Remember the user's query in case they accidentally close the window
this._queryEditorSavedQueryText = this._openQueryEditor.QueryText;
this._openQueryEditor.Dispose();
this._openQueryEditor = null;
};
if (!string.IsNullOrWhiteSpace(this._queryEditorSavedQueryText))
{
this._openQueryEditor.QueryText = this._queryEditorSavedQueryText;
}
this._openQueryEditor.StartPosition = FormStartPosition.Manual;
this._openQueryEditor.Location = this.Location + new Size(30, 30);
this._openQueryEditor.Show(); //don't assign parent so the window can be handled separately by the user
MenuBarClickEvent.FireAndForget(MenuBarClickEvent.ActionId.QueryEditor);
}
else
{
this._openQueryEditor.BringToFront();
}
}
}
}

View file

@ -56,7 +56,7 @@ namespace ParquetViewer
this.exportFileDialog.FilterIndex = (int)defaultFileType + 1;
if (this._openParquetEngine?.Metadata.SchemaTree?.Children.All(s => s.IsPrimitive) == true
&& this._openParquetEngine is Engine.ParquetNET.ParquetEngine)
&& this._openParquetEngine is not Engine.DuckDB.ParquetEngine)
{
this.exportFileDialog.Filter += "|Parquet file (*.parquet)|*.parquet";
}
@ -189,7 +189,9 @@ namespace ParquetViewer
else if (selectedFileType == FileType.PARQUET)
{
ArgumentNullException.ThrowIfNull(engine);
var engineTypeName = engine is Engine.ParquetNET.ParquetEngine ? "ParquetNET" : "DuckDB";
var engineTypeName = engine is Engine.ParquetNET.ParquetEngine ? "ParquetNET" :
engine is Engine.DuckDB.ParquetEngine ? "DuckDB" :
"Unknown";
return WriteDataToParquetFile(engine, dataTable, filePath, cancellationToken, progress, engineTypeName);
}
else
@ -237,7 +239,6 @@ namespace ParquetViewer
string dateFormat = AppSettings.DateTimeDisplayFormat.GetDateFormat();
string dateOnlyFormat = AppSettings.DateTimeDisplayFormat.GetDateOnlyFormat();
string timeOnlyFormat = AppSettings.DateTimeDisplayFormat.GetTimeOnlyFormat();
foreach (DataRowView row in dataTable.DefaultView)
{
rowBuilder.Clear();
@ -267,10 +268,6 @@ namespace ParquetViewer
{
rowBuilder.Append(UtilityMethods.CleanCSVValue(dateOnly.ToString(dateOnlyFormat)));
}
else if (value is TimeOnly timeOnly)
{
rowBuilder.Append(UtilityMethods.CleanCSVValue(timeOnly.ToString(timeOnlyFormat)));
}
else
{
var stringValue = value!.ToString()!; //we never have `null` only `DBNull.Value`
@ -289,7 +286,6 @@ namespace ParquetViewer
{
string dateFormat = AppSettings.DateTimeDisplayFormat.GetDateFormat();
string dateOnlyFormat = AppSettings.DateTimeDisplayFormat.GetDateOnlyFormat();
string timeOnlyFormat = AppSettings.DateTimeDisplayFormat.GetTimeOnlyFormat();
using var fs = new FileStream(path, FileMode.OpenOrCreate);
var excelWriter = new ExcelWriter(fs);
excelWriter.BeginWrite();
@ -331,10 +327,6 @@ namespace ParquetViewer
{
excelWriter.WriteCell(i + 1, j, dateOnly.ToString(dateOnlyFormat));
}
else if (value is TimeOnly timeOnly)
{
excelWriter.WriteCell(i + 1, j, timeOnly.ToString(timeOnlyFormat));
}
else
{
var stringValue = value.ToString();

View file

@ -2,6 +2,7 @@ using ParquetViewer.Analytics;
using ParquetViewer.Controls;
using ParquetViewer.Engine;
using ParquetViewer.Engine.Exceptions;
using ParquetViewer.Exceptions;
using ParquetViewer.Helpers;
using System;
using System.Collections.Generic;
@ -50,6 +51,7 @@ namespace ParquetViewer
this.mainGridView.ClearQuickPeekForms();
this.mainGridView.ClearColumnFormatOverrides();
this.ResetGetSQLCreateTableScriptToolStripMenuItemToolTipText();
this._queryEditorSavedQueryText = null;
if (string.IsNullOrWhiteSpace(this._openFileOrFolderPath))
{
@ -282,8 +284,6 @@ namespace ParquetViewer
if (this._openParquetEngine is null)
return;
#if RELEASE_SELFCONTAINED
//Self contained release has both Parquet.NET and DuckDB engines included as the file size remains the same.
try
{
await this.LoadFileToGridviewImpl(this._openParquetEngine);
@ -298,23 +298,14 @@ namespace ParquetViewer
{
var duckDbEngine = await Engine.DuckDB.ParquetEngine.OpenFileOrFolderAsync(this.OpenFileOrFolderPath!, default);
await LoadFileToGridviewImpl(duckDbEngine);
SwapEngines(duckDbEngine);
this.SwapEngines(duckDbEngine);
}
catch (Exception duckDbEx)
{
//If DuckDB fails too, bail
throw new Exceptions.RowsReadException(unhandledEx, duckDbEx);
throw new RowsReadException(unhandledEx, duckDbEx);
}
}
void SwapEngines(IParquetEngine newEngine)
{
this._openParquetEngine.DisposeSafely();
this._openParquetEngine = newEngine;
}
#else
await this.LoadFileToGridviewImpl(this._openParquetEngine);
#endif
}
private async Task LoadFileToGridviewImpl(IParquetEngine engine)
@ -372,9 +363,9 @@ namespace ParquetViewer
{
HandleSomeFilesSkippedException(ex);
}
catch (FileReadException ex)
catch (Engine.Exceptions.FileReadException ex)
{
HandleFileReadException(ex);
MainForm.HandleFileReadException(ex);
}
catch (MultipleSchemasFoundException ex)
{
@ -411,9 +402,9 @@ namespace ParquetViewer
if (wasSuccessful)
{
var engineType = this._openParquetEngine is Engine.ParquetNET.ParquetEngine
? FileOpenEvent.ParquetEngineTypeId.ParquetNET
: FileOpenEvent.ParquetEngineTypeId.DuckDB;
var engineType = this._openParquetEngine is Engine.DuckDB.ParquetEngine
? FileOpenEvent.ParquetEngineTypeId.DuckDB
: FileOpenEvent.ParquetEngineTypeId.ParquetNET;
FileOpenEvent.FireAndForget(
Directory.Exists(this.OpenFileOrFolderPath),
@ -538,5 +529,11 @@ namespace ParquetViewer
this.englishToolStripMenuItem.Checked = true;
}
}
private void SwapEngines(IParquetEngine newEngine)
{
this._openParquetEngine.DisposeSafely();
this._openParquetEngine = newEngine;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@
<PublishSingleFile>true</PublishSingleFile>
<PublishSelfContained>true</PublishSelfContained>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<Compile Update="Controls\DelayedOnChangedTextBox.cs">
@ -74,16 +74,14 @@
<ItemGroup>
<PackageReference Include="Apache.Arrow" />
<PackageReference Include="dotnet-file-associator" />
<PackageReference Include="FCTB" />
<PackageReference Include="MiniExcel" />
<PackageReference Include="NAudio" />
<PackageReference Include="NAudio.WinForms" />
<PackageReference Include="Parquet.Net" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release_SelfContained'">
<!--We only use DuckDB in the selfcontained release to save on file size-->
<ProjectReference Include="..\ParquetViewer.Engine.DuckDB\ParquetViewer.Engine.DuckDB.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ParquetViewer.Engine.DuckDB\ParquetViewer.Engine.DuckDB.csproj" />
<ProjectReference Include="..\ParquetViewer.Engine.ParquetNET\ParquetViewer.Engine.ParquetNET.csproj" />
<ProjectReference Include="..\ParquetViewer.Engine\ParquetViewer.Engine.csproj" />
</ItemGroup>
@ -105,4 +103,4 @@
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
</Project>

View file

@ -21,4 +21,4 @@ using System.Runtime.Versioning;
// Minor Version
// Patch Version
// Revision
[assembly: AssemblyVersion("4.1.1.0")]
[assembly: AssemblyVersion("4.0.0.0")]

346
src/ParquetViewer/QueryEditor.Designer.cs generated Normal file
View file

@ -0,0 +1,346 @@
using FastColoredTextBoxNS;
using ParquetViewer.Controls;
using System.Windows.Forms;
namespace ParquetViewer
{
partial class QueryEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QueryEditor));
mainSplitContainer = new SplitContainer();
mainTableLayoutPanel = new TableLayoutPanel();
queryRichTextBox = new FastColoredTextBox();
queryEditorContextMenuStrip = new ContextMenuStrip(components);
copyTextMenuItem = new ToolStripMenuItem();
pasteTextMenuItem = new ToolStripMenuItem();
executeQueryButton = new Button();
querySyntaxDocsButton = new Button();
resultsGridView = new ParquetGridView();
statusStrip = new StatusStrip();
toolStripStatusLabel1 = new ToolStripStatusLabel();
showingCountLabel = new ToolStripStatusLabel();
toolStripStatusLabel2 = new ToolStripStatusLabel();
toolStripStatusLabel4 = new ToolStripStatusLabel();
zoomPercentageDropDown = new ToolStripDropDownButton();
percentage100 = new ToolStripMenuItem();
percentage110 = new ToolStripMenuItem();
percentage125 = new ToolStripMenuItem();
percentage140 = new ToolStripMenuItem();
percentage150 = new ToolStripMenuItem();
queryExecutionStatusLabel = new ToolStripStatusLabel();
timeElapsedLabel = new ToolStripStatusLabel();
closeButton = new Button();
executeQueryKeyboardShortcutToolTip = new ToolTip(components);
((System.ComponentModel.ISupportInitialize)mainSplitContainer).BeginInit();
mainSplitContainer.Panel1.SuspendLayout();
mainSplitContainer.Panel2.SuspendLayout();
mainSplitContainer.SuspendLayout();
mainTableLayoutPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)queryRichTextBox).BeginInit();
queryEditorContextMenuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)resultsGridView).BeginInit();
statusStrip.SuspendLayout();
SuspendLayout();
//
// mainSplitContainer
//
resources.ApplyResources(mainSplitContainer, "mainSplitContainer");
mainSplitContainer.BackColor = System.Drawing.SystemColors.Control;
mainSplitContainer.BorderStyle = BorderStyle.FixedSingle;
mainSplitContainer.Name = "mainSplitContainer";
//
// mainSplitContainer.Panel1
//
resources.ApplyResources(mainSplitContainer.Panel1, "mainSplitContainer.Panel1");
mainSplitContainer.Panel1.Controls.Add(mainTableLayoutPanel);
executeQueryKeyboardShortcutToolTip.SetToolTip(mainSplitContainer.Panel1, resources.GetString("mainSplitContainer.Panel1.ToolTip"));
//
// mainSplitContainer.Panel2
//
resources.ApplyResources(mainSplitContainer.Panel2, "mainSplitContainer.Panel2");
mainSplitContainer.Panel2.BackColor = System.Drawing.SystemColors.Control;
mainSplitContainer.Panel2.Controls.Add(resultsGridView);
executeQueryKeyboardShortcutToolTip.SetToolTip(mainSplitContainer.Panel2, resources.GetString("mainSplitContainer.Panel2.ToolTip"));
executeQueryKeyboardShortcutToolTip.SetToolTip(mainSplitContainer, resources.GetString("mainSplitContainer.ToolTip"));
//
// mainTableLayoutPanel
//
resources.ApplyResources(mainTableLayoutPanel, "mainTableLayoutPanel");
mainTableLayoutPanel.Controls.Add(queryRichTextBox, 0, 0);
mainTableLayoutPanel.Controls.Add(executeQueryButton, 0, 1);
mainTableLayoutPanel.Controls.Add(querySyntaxDocsButton, 1, 1);
mainTableLayoutPanel.Name = "mainTableLayoutPanel";
executeQueryKeyboardShortcutToolTip.SetToolTip(mainTableLayoutPanel, resources.GetString("mainTableLayoutPanel.ToolTip"));
//
// queryRichTextBox
//
resources.ApplyResources(queryRichTextBox, "queryRichTextBox");
queryRichTextBox.AutoCompleteBracketsList = new char[]
{
'(',
')',
'{',
'}',
'[',
']',
'"',
'"',
'\'',
'\''
};
queryRichTextBox.AutoIndentCharsPatterns = "";
queryRichTextBox.BackBrush = null;
queryRichTextBox.CharHeight = 16;
queryRichTextBox.CharWidth = 9;
mainTableLayoutPanel.SetColumnSpan(queryRichTextBox, 2);
queryRichTextBox.CommentPrefix = "--";
queryRichTextBox.ContextMenuStrip = queryEditorContextMenuStrip;
queryRichTextBox.DisabledColor = System.Drawing.Color.FromArgb(100, 180, 180, 180);
queryRichTextBox.Hotkeys = resources.GetString("queryRichTextBox.Hotkeys");
queryRichTextBox.IsReplaceMode = false;
queryRichTextBox.Language = Language.SQL;
queryRichTextBox.LeftBracket = '(';
queryRichTextBox.Name = "queryRichTextBox";
queryRichTextBox.Paddings = new Padding(0);
queryRichTextBox.RightBracket = ')';
queryRichTextBox.SelectionColor = System.Drawing.Color.FromArgb(60, 0, 0, 255);
queryRichTextBox.ServiceColors = (ServiceColors)resources.GetObject("queryRichTextBox.ServiceColors");
executeQueryKeyboardShortcutToolTip.SetToolTip(queryRichTextBox, resources.GetString("queryRichTextBox.ToolTip"));
queryRichTextBox.Zoom = 100;
queryRichTextBox.TextChanged += queryRichTextBox_TextChanged;
queryRichTextBox.KeyDown += queryRichTextBox_KeyDown;
//
// queryEditorContextMenuStrip
//
resources.ApplyResources(queryEditorContextMenuStrip, "queryEditorContextMenuStrip");
queryEditorContextMenuStrip.Items.AddRange(new ToolStripItem[] { copyTextMenuItem, pasteTextMenuItem });
queryEditorContextMenuStrip.Name = "queryEditorContextMenuStrip";
executeQueryKeyboardShortcutToolTip.SetToolTip(queryEditorContextMenuStrip, resources.GetString("queryEditorContextMenuStrip.ToolTip"));
//
// copyTextMenuItem
//
resources.ApplyResources(copyTextMenuItem, "copyTextMenuItem");
copyTextMenuItem.Name = "copyTextMenuItem";
copyTextMenuItem.Click += copyTextMenuItem_Click;
//
// pasteTextMenuItem
//
resources.ApplyResources(pasteTextMenuItem, "pasteTextMenuItem");
pasteTextMenuItem.Image = Resources.Icons.paste_icon_24x24;
pasteTextMenuItem.Name = "pasteTextMenuItem";
pasteTextMenuItem.Click += pasteTextMenuItem_Click;
//
// executeQueryButton
//
resources.ApplyResources(executeQueryButton, "executeQueryButton");
executeQueryButton.Image = Resources.Icons.exclamation_icon;
executeQueryButton.Name = "executeQueryButton";
executeQueryKeyboardShortcutToolTip.SetToolTip(executeQueryButton, resources.GetString("executeQueryButton.ToolTip"));
executeQueryButton.UseVisualStyleBackColor = true;
executeQueryButton.Click += executeQueryButton_Click;
//
// querySyntaxDocsButton
//
resources.ApplyResources(querySyntaxDocsButton, "querySyntaxDocsButton");
querySyntaxDocsButton.Image = Resources.Icons.external_link_icon;
querySyntaxDocsButton.Name = "querySyntaxDocsButton";
executeQueryKeyboardShortcutToolTip.SetToolTip(querySyntaxDocsButton, resources.GetString("querySyntaxDocsButton.ToolTip"));
querySyntaxDocsButton.UseVisualStyleBackColor = true;
querySyntaxDocsButton.Click += querySyntaxDocsButton_Click;
//
// resultsGridView
//
resources.ApplyResources(resultsGridView, "resultsGridView");
resultsGridView.AllowUserToAddRows = false;
resultsGridView.AllowUserToDeleteRows = false;
resultsGridView.AllowUserToOrderColumns = true;
resultsGridView.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
resultsGridView.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
resultsGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
resultsGridView.ColumnNameEscapeFormat = "[{0}]";
resultsGridView.CopyAsWhereIcon = null;
resultsGridView.CopyToClipboardIcon = null;
resultsGridView.DateValueEscapeFormat = "#{0}#";
resultsGridView.EnableHeadersVisualStyles = false;
resultsGridView.Name = "resultsGridView";
resultsGridView.ReadOnly = true;
resultsGridView.ShowCellToolTips = false;
resultsGridView.ShowCopyAsWhereContextMenuItem = false;
executeQueryKeyboardShortcutToolTip.SetToolTip(resultsGridView, resources.GetString("resultsGridView.ToolTip"));
//
// statusStrip
//
resources.ApplyResources(statusStrip, "statusStrip");
statusStrip.Items.AddRange(new ToolStripItem[] { toolStripStatusLabel1, showingCountLabel, toolStripStatusLabel2, toolStripStatusLabel4, zoomPercentageDropDown, queryExecutionStatusLabel, timeElapsedLabel });
statusStrip.Name = "statusStrip";
executeQueryKeyboardShortcutToolTip.SetToolTip(statusStrip, resources.GetString("statusStrip.ToolTip"));
//
// toolStripStatusLabel1
//
resources.ApplyResources(toolStripStatusLabel1, "toolStripStatusLabel1");
toolStripStatusLabel1.Name = "toolStripStatusLabel1";
//
// showingCountLabel
//
resources.ApplyResources(showingCountLabel, "showingCountLabel");
showingCountLabel.Name = "showingCountLabel";
//
// toolStripStatusLabel2
//
resources.ApplyResources(toolStripStatusLabel2, "toolStripStatusLabel2");
toolStripStatusLabel2.Name = "toolStripStatusLabel2";
//
// toolStripStatusLabel4
//
resources.ApplyResources(toolStripStatusLabel4, "toolStripStatusLabel4");
toolStripStatusLabel4.Name = "toolStripStatusLabel4";
toolStripStatusLabel4.Spring = true;
//
// zoomPercentageDropDown
//
resources.ApplyResources(zoomPercentageDropDown, "zoomPercentageDropDown");
zoomPercentageDropDown.DisplayStyle = ToolStripItemDisplayStyle.Text;
zoomPercentageDropDown.DropDownItems.AddRange(new ToolStripItem[] { percentage100, percentage110, percentage125, percentage140, percentage150 });
zoomPercentageDropDown.Name = "zoomPercentageDropDown";
//
// percentage100
//
resources.ApplyResources(percentage100, "percentage100");
percentage100.Checked = true;
percentage100.CheckOnClick = true;
percentage100.CheckState = CheckState.Checked;
percentage100.Name = "percentage100";
percentage100.Tag = "100";
percentage100.Click += zoomPercentage_Click;
//
// percentage110
//
resources.ApplyResources(percentage110, "percentage110");
percentage110.Name = "percentage110";
percentage110.Tag = "110";
percentage110.Click += zoomPercentage_Click;
//
// percentage125
//
resources.ApplyResources(percentage125, "percentage125");
percentage125.CheckOnClick = true;
percentage125.Name = "percentage125";
percentage125.Tag = "125";
percentage125.Click += zoomPercentage_Click;
//
// percentage140
//
resources.ApplyResources(percentage140, "percentage140");
percentage140.Name = "percentage140";
percentage140.Tag = "140";
percentage140.Click += zoomPercentage_Click;
//
// percentage150
//
resources.ApplyResources(percentage150, "percentage150");
percentage150.CheckOnClick = true;
percentage150.Name = "percentage150";
percentage150.Tag = "150";
percentage150.Click += zoomPercentage_Click;
//
// queryExecutionStatusLabel
//
resources.ApplyResources(queryExecutionStatusLabel, "queryExecutionStatusLabel");
queryExecutionStatusLabel.Name = "queryExecutionStatusLabel";
//
// timeElapsedLabel
//
resources.ApplyResources(timeElapsedLabel, "timeElapsedLabel");
timeElapsedLabel.Name = "timeElapsedLabel";
//
// closeButton
//
resources.ApplyResources(closeButton, "closeButton");
closeButton.Name = "closeButton";
executeQueryKeyboardShortcutToolTip.SetToolTip(closeButton, resources.GetString("closeButton.ToolTip"));
closeButton.UseVisualStyleBackColor = true;
closeButton.Click += closeButton_Click;
//
// QueryEditor
//
AcceptButton = executeQueryButton;
resources.ApplyResources(this, "$this");
AutoScaleMode = AutoScaleMode.Font;
CancelButton = closeButton;
Controls.Add(closeButton);
Controls.Add(mainSplitContainer);
Controls.Add(statusStrip);
Icon = Resources.Icons.sql_server_icon;
Name = "QueryEditor";
executeQueryKeyboardShortcutToolTip.SetToolTip(this, resources.GetString("$this.ToolTip"));
Load += QueryEditor_Load;
KeyUp += QueryEditor_KeyUp;
mainSplitContainer.Panel1.ResumeLayout(false);
mainSplitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)mainSplitContainer).EndInit();
mainSplitContainer.ResumeLayout(false);
mainTableLayoutPanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)queryRichTextBox).EndInit();
queryEditorContextMenuStrip.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)resultsGridView).EndInit();
statusStrip.ResumeLayout(false);
statusStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.TableLayoutPanel mainTableLayoutPanel;
private FastColoredTextBox queryRichTextBox;
private System.Windows.Forms.Button executeQueryButton;
private System.Windows.Forms.StatusStrip statusStrip;
private Controls.ParquetGridView resultsGridView;
private ToolStripStatusLabel toolStripStatusLabel1;
private ToolStripStatusLabel showingCountLabel;
private ToolStripStatusLabel toolStripStatusLabel2;
private ToolStripStatusLabel queryExecutionStatusLabel;
private ToolStripStatusLabel timeElapsedLabel;
private SplitContainer mainSplitContainer;
private ToolStripDropDownButton zoomPercentageDropDown;
private ToolStripMenuItem percentage100;
private ToolStripMenuItem percentage125;
private ToolStripMenuItem percentage150;
private ToolStripStatusLabel toolStripStatusLabel4;
private ToolStripMenuItem percentage110;
private ToolStripMenuItem percentage140;
private Button querySyntaxDocsButton;
private Button closeButton;
private ToolTip executeQueryKeyboardShortcutToolTip;
private ContextMenuStrip queryEditorContextMenuStrip;
private ToolStripMenuItem copyTextMenuItem;
private ToolStripMenuItem pasteTextMenuItem;
}
}

View file

@ -0,0 +1,460 @@
using DuckDB.NET.Data;
using ParquetViewer.Analytics;
using ParquetViewer.Controls;
using ParquetViewer.Engine;
using ParquetViewer.Engine.Exceptions;
using ParquetViewer.Engine.Types;
using ParquetViewer.Helpers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ParquetViewer
{
public partial class QueryEditor : FormBase
{
private const string QUERY_FORMAT =
@"SELECT {0}
FROM {1}
LIMIT {2}
OFFSET {3} ";
private Brush _splitterColor = Brushes.Silver;
private bool _wasByteArrayConversionErrorShown = false;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string QueryText
{
get => this.queryRichTextBox.Text;
set => this.queryRichTextBox.Text = value;
}
public QueryEditor()
{
InitializeComponent();
this.mainSplitContainer.Paint += MainSplitContainer_Paint;
this.resultsGridView.ShowCopyAsWhereContextMenuItem = true;
this.resultsGridView.CopyAsWhereIcon = Resources.Icons.sql_server_icon.ToBitmap();
this.resultsGridView.ColumnNameEscapeFormat = "\"{0}\"";
this.resultsGridView.DateValueEscapeFormat = "'{0}'";
}
public QueryEditor(IEnumerable<string>? fields = null, string? filePath = null, int offset = 0, int limit = 1000) : this()
{
var filePathSpecified = filePath is not null;
filePath ??= Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? string.Empty, "your-file.parquet");
var queryFields = fields is not null ? string.Join(',', fields.Select(f => $"\"{f}\"")) : "*";
var fromClause = filePath?.EndsWith(".parquet") == true ? $"'{filePath}'" : $"read_parquet('{filePath}')";
this.queryRichTextBox.Text = QUERY_FORMAT.Format(queryFields, fromClause, limit, offset);
if (!filePathSpecified)
this.executeQueryButton.Enabled = false; //start off disabled, so the user has to adjust the query
}
private void QueryEditor_Load(object sender, EventArgs e)
{
this.resultsGridView.AutoGenerateColumns = true;
this.queryExecutionStatusLabel.Visible = false;
this.timeElapsedLabel.Visible = false;
//Set caret to the end of the text
this.queryRichTextBox.SelectionStart = this.queryRichTextBox.Text.Length;
this.queryRichTextBox.SelectionLength = 0;
SetZoom(AppSettings.QueryEditorZoomLevel);
}
private async void executeQueryButton_Click(object sender, EventArgs e)
{
this.executeQueryButton.Enabled = false;
this.Cursor = Cursors.WaitCursor;
this.queryExecutionStatusLabel.Visible = true;
this.timeElapsedLabel.Visible = true;
this.queryExecutionStatusLabel.Text = Resources.Strings.QueryRunningStatusText;
this.timeElapsedLabel.Text = "00:00";
this.resultsGridView.Enabled = false;
var result = new DataTable();
var queryEvent = new ExecuteQueryEvent() { IsDuckDB = true };
try
{
var stopwatch = Stopwatch.StartNew();
var query = this.queryRichTextBox.Text;
var queryTask = Task.Run(() =>
{
using var connection = new DuckDBConnection("Data Source=:memory:");
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = query;
using var reader = command.ExecuteReader();
result.Load(reader);
});
while (!queryTask.IsCompleted)
{
await Task.Delay(100);
this.timeElapsedLabel.Text = stopwatch.Elapsed.ToString("mm\\:ss");
}
stopwatch.Stop();
await queryTask;
this.queryExecutionStatusLabel.Text = Resources.Strings.QueryFinishedStatusText;
this.timeElapsedLabel.Text = stopwatch.Elapsed.ToString("mm\\:ss");
queryEvent.IsValid = true;
queryEvent.RunTimeMS = stopwatch.ElapsedMilliseconds;
queryEvent.RecordCountFiltered = result.Rows.Count;
queryEvent.ColumnCount = result.Columns.Count;
}
catch (Exception ex)
{
result.Dispose();
if (ex is InvalidCastException && ex.Message.Contains("The list contains null value"))
{
MessageBox.Show(Resources.Errors.ListsWithNullsErrorMessage, Resources.Errors.ListsWithNullsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else if (ex is DuckDBException && ex.Message.StartsWith("Parser Error:"))
{
MessageBox.Show($"{Resources.Errors.InvalidQueryErrorMessage}{Environment.NewLine}{Environment.NewLine}{ex.Message}",
Resources.Errors.InvalidQueryErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (ex is OverflowException && ex.Message.Contains("Value was either too large or too small for a Decimal"))
{
MessageBox.Show(Resources.Errors.DecimalValueUnknownSizeTooLargeErrorMessageFormat
.Format(null, null, null,
DecimalOverflowException.MAX_DECIMAL_PRECISION,
DecimalOverflowException.MAX_DECIMAL_SCALE),
Resources.Errors.DecimalValueTooLargeErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
ExceptionEvent.FireAndForget(ex);
MessageBox.Show(ex.Message, Resources.Errors.QueryExecutionErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
this.executeQueryButton.Enabled = true;
this.resultsGridView.Enabled = true;
this.Cursor = Cursors.Default;
return;
}
finally
{
//Fire and forget
var _ = queryEvent.Record();
}
//Cleanup previous results
if (this.resultsGridView.DataSource is DataTable dt)
{
dt.Dispose();
}
try
{
this.resultsGridView.DataSource = ConvertValues(result);
this.showingCountLabel.Text = result.Rows.Count.ToString();
}
catch (Exception ex)
{
ExceptionEvent.FireAndForget(ex);
MessageBox.Show($"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}",
Resources.Errors.RenderResultsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
this.executeQueryButton.Enabled = true;
this.resultsGridView.Enabled = true;
this.Cursor = Cursors.Default;
}
}
private void queryRichTextBox_TextChanged(object sender, FastColoredTextBoxNS.TextChangedEventArgs e)
{
this.executeQueryButton.Enabled = true;
}
private void zoomPercentage_Click(object sender, EventArgs e)
{
if (sender is ToolStripMenuItem menuItem && int.TryParse(menuItem.Tag?.ToString(), out int zoomPercentage))
{
SetZoom(zoomPercentage);
}
}
private void SetZoom(int? zoomPercentage)
{
zoomPercentage = Math.Clamp(zoomPercentage ?? 100, 100, 150);
this.queryRichTextBox.Zoom = zoomPercentage.Value;
this.zoomPercentageDropDown.Text = Resources.Strings.QueryZoomStatusTextFormat.Format(zoomPercentage);
AppSettings.QueryEditorZoomLevel = zoomPercentage.Value;
foreach (ToolStripMenuItem menuItem in this.zoomPercentageDropDown.DropDownItems)
{
menuItem.Checked = int.TryParse(menuItem.Tag?.ToString(), out int percentage) && percentage == zoomPercentage.Value;
}
}
private void querySyntaxDocsButton_Click(object sender, EventArgs e)
{
Process.Start(new ProcessStartInfo(Constants.DuckDBSqlSyntaxURL) { UseShellExecute = true });
}
private void queryRichTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F5 || (e.Shift && e.KeyCode == Keys.Enter))
{
executeQueryButton.PerformClick();
e.Handled = true;
e.SuppressKeyPress = true;
}
}
private void QueryEditor_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == (int)Keys.Escape)
{
this.Close();
e.Handled = true;
}
}
private void closeButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void MainSplitContainer_Paint(object? sender, PaintEventArgs e)
{
//Draw a line where the splitter is so users can tell they can resize the sections
var splitContainer = sender as SplitContainer;
if (splitContainer != null)
{
var rectangle = splitContainer.SplitterRectangle;
rectangle.Offset(0, 1);
rectangle.Height -= 2;
e.Graphics.FillRectangle(_splitterColor, rectangle);
}
}
private DataTable ConvertValues(DataTable intermediateResult)
{
var hasComplexType = false;
foreach (DataColumn column in intermediateResult.Columns)
{
if (column.DataType.ImplementsInterface<IDictionary>()
|| column.DataType.ImplementsInterface<IList>()
|| column.DataType == typeof(Stream))
{
hasComplexType = true;
break;
}
}
if (!hasComplexType)
{
//Nothing to convert
return intermediateResult;
}
var result = new DataTable();
foreach (DataColumn column in intermediateResult.Columns)
{
if (column.DataType == typeof(Dictionary<string, object?>))
{
result.Columns.Add(new DataColumn(column.ColumnName, typeof(StructValue)));
}
else if (column.DataType.ImplementsInterface<IList>())
{
result.Columns.Add(new DataColumn(column.ColumnName, typeof(ListValue)));
}
else if (column.DataType.ImplementsInterface<IDictionary>())
{
result.Columns.Add(new DataColumn(column.ColumnName, typeof(MapValue)));
}
else if (column.DataType == typeof(Stream))
{
result.Columns.Add(new DataColumn(column.ColumnName, typeof(ByteArrayValue)));
}
else
{
result.Columns.Add(new DataColumn(column.ColumnName, column.DataType));
}
}
result.BeginLoadData();
foreach (DataRow row in intermediateResult.Rows)
{
var newRow = result.NewRow();
for (var i = 0; i < row.ItemArray.Length; i++)
{
var value = row.ItemArray[i];
newRow[i] = ConvertValue(value!);
}
result.Rows.Add(newRow);
}
result.EndLoadData();
return result;
}
private object ConvertValue(object? value)
{
if (value == DBNull.Value || value is null)
{
return DBNull.Value;
}
else if (value is Dictionary<string, object?> structDictionary)
{
var dataRow = new QueryResultDataRow(structDictionary.Keys.ToList(),
structDictionary.Values.Select(ConvertValue).ToArray());
var structValue = new StructValue(dataRow);
return structValue;
}
else if (value is IList list)
{
var arrayList = new ArrayList(list.Count);
var listType = typeof(object);
for (var i = 0; i < list.Count; i++)
{
var convertedListValue = ConvertValue(list[i]);
arrayList.Add(convertedListValue);
if (convertedListValue != DBNull.Value)
{
listType = convertedListValue.GetType();
}
}
var listValue = new ListValue(arrayList, listType);
return listValue;
}
else if (value is IDictionary dictionary)
{
var keysList = new ArrayList(dictionary.Keys.Count);
var valuesList = new ArrayList(dictionary.Values.Count);
var keysType = typeof(object);
var valuesType = typeof(object);
foreach (var keyValuePair in Engine.Helpers.PairEnumerables(
dictionary.Keys.OfType<object?>(),
dictionary.Values.OfType<object?>(),
DBNull.Value))
{
var convertedKey = ConvertValue(keyValuePair.Item1);
var convertedValue = ConvertValue(keyValuePair.Item2);
keysList.Add(convertedKey);
valuesList.Add(convertedValue);
if (convertedKey != DBNull.Value)
{
keysType = convertedKey.GetType();
}
if (convertedValue != DBNull.Value)
{
valuesType = convertedValue.GetType();
}
}
var mapValue = new MapValue(
keysList, keysType,
valuesList, valuesType);
return mapValue;
}
else if (value is Stream byteArray)
{
//DuckDB doesn't seem to like byte array values. It fails to read after the first row with a memory access violation error.
if (!this._wasByteArrayConversionErrorShown)
{
this._wasByteArrayConversionErrorShown = true;
MessageBox.Show(
Resources.Strings.ByteArraysNotSupportedErrorMessage,
Resources.Strings.ByteArraysNotSupportedErrorTitle,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
return DBNull.Value;
/*
using var ms = new MemoryStream();
byteArray.CopyTo(ms); //MemoryAccessViolation thrown here on second row and beyond
var byteArrayValue = new ByteArrayValue(ms.ToArray());
return byteArrayValue;
*/
}
else
{
return value;
}
}
private class QueryResultDataRow : IDataRowLite
{
public IReadOnlyCollection<string> ColumnNames { get; }
public object[] Row { get; }
public QueryResultDataRow(List<string> columnNames, object[] data)
{
this.ColumnNames = columnNames.AsReadOnly();
this.Row = data;
}
public object GetValue(string columnName)
{
var result = this.ColumnNames.Index().Where(pair => pair.Item == columnName).FirstOrDefault();
if (result == default)
throw new ArgumentOutOfRangeException($"Column `{columnName}` doesn't exist");
return this.Row[result.Index];
}
}
public override void SetTheme(Theme theme)
{
if (DesignMode)
{
return;
}
base.SetTheme(theme);
this.resultsGridView.GridTheme = theme;
this.querySyntaxDocsButton.ForeColor = Color.Black;
this.executeQueryButton.ForeColor = Color.Black;
this.statusStrip.BackColor = theme.FormBackgroundColor;
this.statusStrip.ForeColor = theme.TextColor;
this.mainTableLayoutPanel.BackColor = theme.FormBackgroundColor;
this._splitterColor = new SolidBrush(theme.DisabledTextColor);
this.queryRichTextBox.IndentBackColor = theme.RowHeaderColor;
this.queryRichTextBox.ForeColor = theme.TextColor;
this.queryRichTextBox.SelectionColor = theme.SelectionBackColor;
this.queryRichTextBox.CaretColor = theme.TextColor;
if (theme == Theme.LightModeTheme)
{
this.queryRichTextBox.BackColor = Color.White;
}
else
{
this.queryRichTextBox.BackColor = theme.CellBackgroundColor;
}
this.statusStrip.Renderer = theme.ToolStripRenderer;
}
private void copyTextMenuItem_Click(object sender, EventArgs e)
{
this.queryRichTextBox.Copy();
}
private void pasteTextMenuItem_Click(object sender, EventArgs e)
{
this.queryRichTextBox.Paste();
}
}
}

View file

@ -0,0 +1,690 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="&gt;&gt;mainSplitContainer.Panel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;percentage110.Name" xml:space="preserve">
<value>percentage110</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="mainTableLayoutPanel.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="queryRichTextBox" Row="0" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;Control Name="executeQueryButton" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="querySyntaxDocsButton" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100,Absolute,130" /&gt;&lt;Rows Styles="Percent,100,Absolute,32" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;percentage150.Name" xml:space="preserve">
<value>percentage150</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="mainSplitContainer.SplitterWidth" type="System.Int32, mscorlib">
<value>6</value>
</data>
<data name="queryRichTextBox.ToolTip" xml:space="preserve">
<value />
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="percentage150.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="closeButton.Location" type="System.Drawing.Point, System.Drawing">
<value>942, 221</value>
</data>
<data name="mainSplitContainer.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;executeQueryButton.Parent" xml:space="preserve">
<value>mainTableLayoutPanel</value>
</data>
<data name="&gt;&gt;percentage150.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;closeButton.Name" xml:space="preserve">
<value>closeButton</value>
</data>
<data name="querySyntaxDocsButton.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;percentage125.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;copyTextMenuItem.Name" xml:space="preserve">
<value>copyTextMenuItem</value>
</data>
<data name="mainSplitContainer.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="queryRichTextBox.Size" type="System.Drawing.Size, System.Drawing">
<value>973, 108</value>
</data>
<data name="&gt;&gt;querySyntaxDocsButton.Name" xml:space="preserve">
<value>querySyntaxDocsButton</value>
</data>
<data name="&gt;&gt;querySyntaxDocsButton.Parent" xml:space="preserve">
<value>mainTableLayoutPanel</value>
</data>
<data name="percentage150.Text" xml:space="preserve">
<value>150%</value>
</data>
<data name="mainSplitContainer.Size" type="System.Drawing.Size, System.Drawing">
<value>981, 368</value>
</data>
<data name="&gt;&gt;queryExecutionStatusLabel.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="statusStrip.ToolTip" xml:space="preserve">
<value />
</data>
<data name="queryRichTextBox.Hotkeys" xml:space="preserve">
<value>Tab=IndentIncrease, Escape=ClearHints, PgUp=GoPageUp, PgDn=GoPageDown, End=GoEnd, Home=GoHome, Left=GoLeft, Up=GoUp, Right=GoRight, Down=GoDown, Insert=ReplaceMode, Del=DeleteCharRight, F3=FindNext, Shift+Tab=IndentDecrease, Shift+PgUp=GoPageUpWithSelection, Shift+PgDn=GoPageDownWithSelection, Shift+End=GoEndWithSelection, Shift+Home=GoHomeWithSelection, Shift+Left=GoLeftWithSelection, Shift+Up=GoUpWithSelection, Shift+Right=GoRightWithSelection, Shift+Down=GoDownWithSelection, Shift+Insert=Paste, Shift+Del=Cut, Ctrl+Back=ClearWordLeft, Ctrl+Space=AutocompleteMenu, Ctrl+End=GoLastLine, Ctrl+Home=GoFirstLine, Ctrl+Left=GoWordLeft, Ctrl+Up=ScrollUp, Ctrl+Right=GoWordRight, Ctrl+Down=ScrollDown, Ctrl+Insert=Copy, Ctrl+Del=ClearWordRight, Ctrl+0=ZoomNormal, Ctrl+A=SelectAll, Ctrl+B=BookmarkLine, Ctrl+C=Copy, Ctrl+E=MacroExecute, Ctrl+F=FindDialog, Ctrl+G=GoToDialog, Ctrl+H=ReplaceDialog, Ctrl+I=AutoIndentChars, Ctrl+M=MacroRecord, Ctrl+N=GoNextBookmark, Ctrl+R=Redo, Ctrl+U=UpperCase, Ctrl+V=Paste, Ctrl+X=Cut, Ctrl+Z=Undo, Ctrl+Add=ZoomIn, Ctrl+Subtract=ZoomOut, Ctrl+OemMinus=NavigateBackward, Ctrl+Shift+End=GoLastLineWithSelection, Ctrl+Shift+Home=GoFirstLineWithSelection, Ctrl+Shift+Left=GoWordLeftWithSelection, Ctrl+Shift+Right=GoWordRightWithSelection, Ctrl+Shift+B=UnbookmarkLine, Ctrl+Shift+C=CommentSelected, Ctrl+Shift+N=GoPrevBookmark, Ctrl+Shift+U=LowerCase, Ctrl+Shift+OemMinus=NavigateForward, Alt+Back=Undo, Alt+Up=MoveSelectedLinesUp, Alt+Down=MoveSelectedLinesDown, Alt+F=FindChar, Alt+Shift+Left=GoLeft_ColumnSelectionMode, Alt+Shift+Up=GoUp_ColumnSelectionMode, Alt+Shift+Right=GoRight_ColumnSelectionMode, Alt+Shift+Down=GoDown_ColumnSelectionMode</value>
</data>
<data name="resultsGridView.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="executeQueryButton.Size" type="System.Drawing.Size, System.Drawing">
<value>843, 26</value>
</data>
<data name="&gt;&gt;queryExecutionStatusLabel.Name" xml:space="preserve">
<value>queryExecutionStatusLabel</value>
</data>
<data name="resultsGridView.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="toolStripStatusLabel2.Size" type="System.Drawing.Size, System.Drawing">
<value>44, 17</value>
</data>
<data name="timeElapsedLabel.Text" xml:space="preserve">
<value>00:00</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Panel2.Type" xml:space="preserve">
<value>System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="mainTableLayoutPanel.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="&gt;&gt;statusStrip.Name" xml:space="preserve">
<value>statusStrip</value>
</data>
<data name="&gt;&gt;toolStripStatusLabel4.Name" xml:space="preserve">
<value>toolStripStatusLabel4</value>
</data>
<data name="&gt;&gt;statusStrip.Type" xml:space="preserve">
<value>System.Windows.Forms.StatusStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;querySyntaxDocsButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="querySyntaxDocsButton.Text" xml:space="preserve">
<value>Query Syntax</value>
</data>
<data name="percentage125.Text" xml:space="preserve">
<value>125%</value>
</data>
<data name="&gt;&gt;timeElapsedLabel.Name" xml:space="preserve">
<value>timeElapsedLabel</value>
</data>
<data name="executeQueryButton.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 117</value>
</data>
<data name="&gt;&gt;pasteTextMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;percentage100.Name" xml:space="preserve">
<value>percentage100</value>
</data>
<data name="resultsGridView.Size" type="System.Drawing.Size, System.Drawing">
<value>979, 212</value>
</data>
<data name="&gt;&gt;showingCountLabel.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;resultsGridView.Parent" xml:space="preserve">
<value>mainSplitContainer.Panel2</value>
</data>
<data name="statusStrip.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>ParquetViewer.Controls.FormBase, ParquetViewer, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Panel1.Parent" xml:space="preserve">
<value>mainSplitContainer</value>
</data>
<data name="&gt;&gt;copyTextMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>7, 15</value>
</data>
<data name="$this.MinimumSize" type="System.Drawing.Size, System.Drawing">
<value>490, 340</value>
</data>
<data name="percentage110.Text" xml:space="preserve">
<value>110%</value>
</data>
<data name="timeElapsedLabel.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Bold</value>
</data>
<data name="&gt;&gt;statusStrip.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Panel2.Parent" xml:space="preserve">
<value>mainSplitContainer</value>
</data>
<data name="&gt;&gt;zoomPercentageDropDown.Name" xml:space="preserve">
<value>zoomPercentageDropDown</value>
</data>
<data name="percentage100.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="queryRichTextBox.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Panel1.Name" xml:space="preserve">
<value>mainSplitContainer.Panel1</value>
</data>
<data name="statusStrip.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 368</value>
</data>
<data name="mainTableLayoutPanel.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;executeQueryKeyboardShortcutToolTip.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolTip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;mainTableLayoutPanel.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;queryEditorContextMenuStrip.Name" xml:space="preserve">
<value>queryEditorContextMenuStrip</value>
</data>
<data name="executeQueryButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="&gt;&gt;queryRichTextBox.Parent" xml:space="preserve">
<value>mainTableLayoutPanel</value>
</data>
<data name="percentage140.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="mainSplitContainer.Panel1.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;zoomPercentageDropDown.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripDropDownButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="toolStripStatusLabel4.Size" type="System.Drawing.Size, System.Drawing">
<value>638, 17</value>
</data>
<data name="zoomPercentageDropDown.ImageTransparentColor" type="System.Drawing.Color, System.Drawing">
<value>Magenta</value>
</data>
<data name="mainSplitContainer.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="&gt;&gt;executeQueryKeyboardShortcutToolTip.Name" xml:space="preserve">
<value>executeQueryKeyboardShortcutToolTip</value>
</data>
<data name="resultsGridView.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="executeQueryButton.Text" xml:space="preserve">
<value>Execute</value>
</data>
<data name="queryExecutionStatusLabel.Text" xml:space="preserve">
<value>Running:</value>
</data>
<data name="$this.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;toolStripStatusLabel1.Name" xml:space="preserve">
<value>toolStripStatusLabel1</value>
</data>
<data name="&gt;&gt;mainTableLayoutPanel.Name" xml:space="preserve">
<value>mainTableLayoutPanel</value>
</data>
<data name="&gt;&gt;toolStripStatusLabel4.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>ParquetViewer - Query Editor (Powered by DuckDB)</value>
</data>
<data name="&gt;&gt;queryRichTextBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="percentage110.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="queryEditorContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>103, 48</value>
</data>
<data name="mainSplitContainer.Panel1MinSize" type="System.Int32, mscorlib">
<value>120</value>
</data>
<data name="querySyntaxDocsButton.TextImageRelation" type="System.Windows.Forms.TextImageRelation, System.Windows.Forms">
<value>ImageBeforeText</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>981, 390</value>
</data>
<data name="mainTableLayoutPanel.ToolTip" xml:space="preserve">
<value />
</data>
<data name="querySyntaxDocsButton.ToolTip" xml:space="preserve">
<value />
</data>
<data name="zoomPercentageDropDown.Text" xml:space="preserve">
<value>Query Zoom: 100%</value>
</data>
<data name="&gt;&gt;queryEditorContextMenuStrip.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="querySyntaxDocsButton.Location" type="System.Drawing.Point, System.Drawing">
<value>852, 117</value>
</data>
<data name="executeQueryButton.TextImageRelation" type="System.Windows.Forms.TextImageRelation, System.Windows.Forms">
<value>ImageBeforeText</value>
</data>
<data name="&gt;&gt;executeQueryButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;executeQueryButton.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="queryEditorContextMenuStrip.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;closeButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;closeButton.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="queryRichTextBox.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="zoomPercentageDropDown.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wgAADsIBFShKgAAAAI1JREFUOE9j+Pbt239KMAOIcHJyIgujGPDh/UeSMMkGPL918v+JblMwTZYBJ7pN
/h+qlQIbQpYBEBeYEHbBpLOv/i+49BrDAHSM1YCsfS/+Sy98BMaEDMEwAFkzMYagGKDTsBJDMzZDQOzW
Ey8xDUDXhI5BGkEYxge5liQDsGGQqykyAISpZwAlmIFSAAAHNfyc4iTN4wAAAABJRU5ErkJggg==
</value>
</data>
<data name="showingCountLabel.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 9pt, style=Bold</value>
</data>
<data name="&gt;&gt;statusStrip.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="mainSplitContainer.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="toolStripStatusLabel1.Text" xml:space="preserve">
<value>Showing:</value>
</data>
<data name="statusStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>981, 22</value>
</data>
<data name="showingCountLabel.Text" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;resultsGridView.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Type" xml:space="preserve">
<value>System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;percentage140.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="querySyntaxDocsButton.Size" type="System.Drawing.Size, System.Drawing">
<value>124, 26</value>
</data>
<data name="&gt;&gt;closeButton.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="copyTextMenuItem.Text" xml:space="preserve">
<value>Copy</value>
</data>
<data name="mainTableLayoutPanel.Size" type="System.Drawing.Size, System.Drawing">
<value>979, 146</value>
</data>
<data name="pasteTextMenuItem.Text" xml:space="preserve">
<value>Paste</value>
</data>
<data name="&gt;&gt;resultsGridView.Name" xml:space="preserve">
<value>resultsGridView</value>
</data>
<data name="zoomPercentageDropDown.Size" type="System.Drawing.Size, System.Drawing">
<value>121, 20</value>
</data>
<data name="showingCountLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>14, 17</value>
</data>
<data name="mainTableLayoutPanel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="executeQueryButton.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="mainSplitContainer.SplitterDistance" type="System.Int32, mscorlib">
<value>148</value>
</data>
<data name="queryExecutionStatusLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>55, 17</value>
</data>
<data name="&gt;&gt;toolStripStatusLabel1.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;mainSplitContainer.Name" xml:space="preserve">
<value>mainSplitContainer</value>
</data>
<data name="&gt;&gt;executeQueryButton.Name" xml:space="preserve">
<value>executeQueryButton</value>
</data>
<data name="&gt;&gt;toolStripStatusLabel2.Name" xml:space="preserve">
<value>toolStripStatusLabel2</value>
</data>
<data name="executeQueryButton.ImageAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleRight</value>
</data>
<data name="queryRichTextBox.AutoScrollMinSize" type="System.Drawing.Size, System.Drawing">
<value>29, 16</value>
</data>
<data name="queryRichTextBox.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAERGYXN0Q29sb3JlZFRleHRCb3gsIEN1bHR1cmU9bmV1dHJhbCwg
UHVibGljS2V5VG9rZW49ZmI4YWExMmI5OTRlZjYxYgwDAAAAUVN5c3RlbS5EcmF3aW5nLCBWZXJzaW9u
PTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUB
AAAAIkZhc3RDb2xvcmVkVGV4dEJveE5TLlNlcnZpY2VDb2xvcnMGAAAAKDxDb2xsYXBzZU1hcmtlckZv
cmVDb2xvcj5rX19CYWNraW5nRmllbGQoPENvbGxhcHNlTWFya2VyQmFja0NvbG9yPmtfX0JhY2tpbmdG
aWVsZCo8Q29sbGFwc2VNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtl
ckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtlckJhY2tDb2xvcj5rX19CYWNraW5n
RmllbGQoPEV4cGFuZE1hcmtlckJvcmRlckNvbG9yPmtfX0JhY2tpbmdGaWVsZAQEBAQEBBRTeXN0ZW0u
RHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNv
bG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5
c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAIAAAAF/P///xRTeXN0ZW0uRHJhd2luZy5Db2xvcgQAAAAEbmFt
ZQV2YWx1ZQprbm93bkNvbG9yBXN0YXRlAQAAAAkHBwMAAAAKAAAAAAAAAACWAAEAAfv////8////CgAA
AAAAAAAApAABAAH6/////P///woAAAAAAAAAAJYAAQAB+f////z///8KAAAAAAAAAACNAAEAAfj////8
////CgAAAAAAAAAApAABAAH3/////P///woAAAAAAAAAAJYAAQAL
</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>QueryEditor</value>
</data>
<data name="&gt;&gt;querySyntaxDocsButton.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="closeButton.Text" xml:space="preserve">
<value>Close</value>
</data>
<data name="percentage125.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="resultsGridView.ToolTip" xml:space="preserve">
<value />
</data>
<data name="timeElapsedLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>38, 17</value>
</data>
<data name="executeQueryButton.ToolTip" xml:space="preserve">
<value>(Shift + Enter)</value>
</data>
<data name="&gt;&gt;queryRichTextBox.Type" xml:space="preserve">
<value>FastColoredTextBoxNS.FastColoredTextBox, FastColoredTextBox, Culture=neutral, PublicKeyToken=fb8aa12b994ef61b</value>
</data>
<data name="percentage140.Text" xml:space="preserve">
<value>140%</value>
</data>
<data name="mainTableLayoutPanel.ColumnCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;showingCountLabel.Name" xml:space="preserve">
<value>showingCountLabel</value>
</data>
<data name="resultsGridView.RowHeadersWidth" type="System.Int32, mscorlib">
<value>24</value>
</data>
<data name="querySyntaxDocsButton.ImageAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleRight</value>
</data>
<data name="closeButton.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="copyTextMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wQAADsEBuJFr7QAAAw9JREFUWEftVs1PE0EU7x9AgvGmBsO+mW6d3e6WphjxiwIS/wRuHPSiR/4Cs+3y
UZVvotGTN24EjCa6uzTY8FksRCySKPHgQf8DuI6+tdM0UygtNOiBX/Ky2Xlv3vx25rfzXiBwhioQS+Ua
meXN6JaT1ZLu0mHGLGdDs9P35PknhmmnuyJT29wc3eSRyTyPTG5Llufm+CduDK9zc3SDh/vdh3KOE8Gw
F7pbnn/luuXsGkPp9ojtdZSaMeS06/3zffpghocfr/hkNHv+gZzn2IiOZa8bIznO7PQb2SfQmvSi4Sdr
nCXcfZ/ExOf6kjgK/m5M5rmWdObMQbfXnNjyj6ZmErFYrJEQMgMAWULIEhooSkZpuvAOLl/yxBildINS
el/Mi9jpu9GX3zmzXAffw8l0D+6IOb5VmyY0TesKhUJcVVWOz4MMfcFgUMT4yVufrTdpAx84s7yfLXb6
RiS5qLOEN22MfPTFWzUJQkgnJqaUbgeDwfZQKNRRajgGAH2EEIwRZPxtvjqYVVnC5dEXuxyPIJxa9kXp
P5+ucSPpGfJ6ZSgshMkXZJ8ApTSKOwAA+0gC4wWJ2HDuipZwN1nSyTHLWdYsN6NZzh6KWE+875RzlUEQ
UBRlUfYJlJCcU1W1VxyXICEDLyn/rkh5t2RfGURyFJrsExAxAODiu6qqPUVNAJSdNUs6K3UlIHRCCMmr
qnqTMaYTQqZlYQowy1utKwHGWHfpn1IQbdEK+igKru4E2traziuK8hbvAgBYI4SsUkqXASADAHtIAHdJ
xNedQCXgvII+ioudKgFK6co/JYDHcUbgvyCANUOM6Za7iJ3TKRJQebC5+Vp06sdF03a6tIS3g10Ss50i
qUNRDwJ4MamBgGJO7TyKvfrFzbG/vWTLgBuX48tQLwK0oUELT3zp0RLeN6yOmuXMxlJeoxxfhmqqYSUc
pIGaUFJqD+0HKgGJ43zG2G3ZVxVKKx3+SrUaIWSn0CUdbwcA4A5+QaWesJKJeZTSowV3EOLx+DlK6evS
SletYXyhW54FgKMFd4Y/+A3rSyMPm3Pf6gAAAABJRU5ErkJggg==
</value>
</data>
<data name="&gt;&gt;mainSplitContainer.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="percentage100.Text" xml:space="preserve">
<value>100%</value>
</data>
<data name="toolStripStatusLabel2.Text" xml:space="preserve">
<value>Results</value>
</data>
<data name="&gt;&gt;percentage100.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;percentage140.Name" xml:space="preserve">
<value>percentage140</value>
</data>
<data name="queryRichTextBox.Font" type="System.Drawing.Font, System.Drawing">
<value>Courier New, 11.25pt</value>
</data>
<data name="&gt;&gt;toolStripStatusLabel2.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;timeElapsedLabel.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;mainTableLayoutPanel.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;mainTableLayoutPanel.Parent" xml:space="preserve">
<value>mainSplitContainer.Panel1</value>
</data>
<data name="mainSplitContainer.Panel2MinSize" type="System.Int32, mscorlib">
<value>150</value>
</data>
<data name="mainTableLayoutPanel.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="mainSplitContainer.Orientation" type="System.Windows.Forms.Orientation, System.Windows.Forms">
<value>Horizontal</value>
</data>
<data name="queryRichTextBox.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="copyTextMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="closeButton.Size" type="System.Drawing.Size, System.Drawing">
<value>0, 0</value>
</data>
<data name="closeButton.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;mainSplitContainer.Panel2.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="querySyntaxDocsButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="pasteTextMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 22</value>
</data>
<data name="&gt;&gt;percentage125.Name" xml:space="preserve">
<value>percentage125</value>
</data>
<data name="&gt;&gt;pasteTextMenuItem.Name" xml:space="preserve">
<value>pasteTextMenuItem</value>
</data>
<data name="&gt;&gt;queryRichTextBox.Name" xml:space="preserve">
<value>queryRichTextBox</value>
</data>
<data name="mainSplitContainer.Panel2.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;mainSplitContainer.Panel2.Name" xml:space="preserve">
<value>mainSplitContainer.Panel2</value>
</data>
<data name="&gt;&gt;percentage110.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="toolStripStatusLabel1.Size" type="System.Drawing.Size, System.Drawing">
<value>56, 17</value>
</data>
<data name="&gt;&gt;resultsGridView.Type" xml:space="preserve">
<value>ParquetViewer.Controls.ParquetGridView, ParquetViewer, Culture=neutral, PublicKeyToken=null</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="executeQueryKeyboardShortcutToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>126, 17</value>
</metadata>
<metadata name="queryEditorContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>387, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,251 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="mainTableLayoutPanel.ToolTip" xml:space="preserve">
<value />
</data>
<data name="mainSplitContainer.Panel1.ToolTip" xml:space="preserve">
<value />
</data>
<data name="resultsGridView.ToolTip" xml:space="preserve">
<value />
</data>
<data name="mainSplitContainer.Panel2.ToolTip" xml:space="preserve">
<value />
</data>
<data name="mainSplitContainer.ToolTip" xml:space="preserve">
<value />
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="queryEditorContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>117, 48</value>
</data>
<data name="queryEditorContextMenuStrip.ToolTip" xml:space="preserve">
<value />
</data>
<data name="queryRichTextBox.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAERGYXN0Q29sb3JlZFRleHRCb3gsIEN1bHR1cmU9bmV1dHJhbCwg
UHVibGljS2V5VG9rZW49ZmI4YWExMmI5OTRlZjYxYgwDAAAAUVN5c3RlbS5EcmF3aW5nLCBWZXJzaW9u
PTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYQUB
AAAAIkZhc3RDb2xvcmVkVGV4dEJveE5TLlNlcnZpY2VDb2xvcnMGAAAAKDxDb2xsYXBzZU1hcmtlckZv
cmVDb2xvcj5rX19CYWNraW5nRmllbGQoPENvbGxhcHNlTWFya2VyQmFja0NvbG9yPmtfX0JhY2tpbmdG
aWVsZCo8Q29sbGFwc2VNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtl
ckZvcmVDb2xvcj5rX19CYWNraW5nRmllbGQmPEV4cGFuZE1hcmtlckJhY2tDb2xvcj5rX19CYWNraW5n
RmllbGQoPEV4cGFuZE1hcmtlckJvcmRlckNvbG9yPmtfX0JhY2tpbmdGaWVsZAQEBAQEBBRTeXN0ZW0u
RHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNv
bG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5
c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAIAAAAF/P///xRTeXN0ZW0uRHJhd2luZy5Db2xvcgQAAAAEbmFt
ZQV2YWx1ZQprbm93bkNvbG9yBXN0YXRlAQAAAAkHBwMAAAAKAAAAAAAAAACWAAEAAfv////8////CgAA
AAAAAAAApAABAAH6/////P///woAAAAAAAAAAJYAAQAB+f////z///8KAAAAAAAAAACNAAEAAfj////8
////CgAAAAAAAAAApAABAAH3/////P///woAAAAAAAAAAJYAAQAL
</value>
</data>
<data name="queryRichTextBox.ToolTip" xml:space="preserve">
<value />
</data>
<data name="copyTextMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wQAADsEBuJFr7QAAAw9JREFUWEftVs1PE0EU7x9AgvGmBsO+mW6d3e6WphjxiwIS/wRuHPSiR/4Cs+3y
UZVvotGTN24EjCa6uzTY8FksRCySKPHgQf8DuI6+tdM0UygtNOiBX/Ky2Xlv3vx25rfzXiBwhioQS+Ua
meXN6JaT1ZLu0mHGLGdDs9P35PknhmmnuyJT29wc3eSRyTyPTG5Llufm+CduDK9zc3SDh/vdh3KOE8Gw
F7pbnn/luuXsGkPp9ojtdZSaMeS06/3zffpghocfr/hkNHv+gZzn2IiOZa8bIznO7PQb2SfQmvSi4Sdr
nCXcfZ/ExOf6kjgK/m5M5rmWdObMQbfXnNjyj6ZmErFYrJEQMgMAWULIEhooSkZpuvAOLl/yxBildINS
el/Mi9jpu9GX3zmzXAffw8l0D+6IOb5VmyY0TesKhUJcVVWOz4MMfcFgUMT4yVufrTdpAx84s7yfLXb6
RiS5qLOEN22MfPTFWzUJQkgnJqaUbgeDwfZQKNRRajgGAH2EEIwRZPxtvjqYVVnC5dEXuxyPIJxa9kXp
P5+ucSPpGfJ6ZSgshMkXZJ8ApTSKOwAA+0gC4wWJ2HDuipZwN1nSyTHLWdYsN6NZzh6KWE+875RzlUEQ
UBRlUfYJlJCcU1W1VxyXICEDLyn/rkh5t2RfGURyFJrsExAxAODiu6qqPUVNAJSdNUs6K3UlIHRCCMmr
qnqTMaYTQqZlYQowy1utKwHGWHfpn1IQbdEK+igKru4E2traziuK8hbvAgBYI4SsUkqXASADAHtIAHdJ
xNedQCXgvII+ioudKgFK6co/JYDHcUbgvyCANUOM6Za7iJ3TKRJQebC5+Vp06sdF03a6tIS3g10Ss50i
qUNRDwJ4MamBgGJO7TyKvfrFzbG/vWTLgBuX48tQLwK0oUELT3zp0RLeN6yOmuXMxlJeoxxfhmqqYSUc
pIGaUFJqD+0HKgGJ43zG2G3ZVxVKKx3+SrUaIWSn0CUdbwcA4A5+QaWesJKJeZTSowV3EOLx+DlK6evS
SletYXyhW54FgKMFd4Y/+A3rSyMPm3Pf6gAAAABJRU5ErkJggg==
</value>
</data>
<data name="copyTextMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>116, 22</value>
</data>
<data name="copyTextMenuItem.Text" xml:space="preserve">
<value>Kopyala</value>
</data>
<data name="pasteTextMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>116, 22</value>
</data>
<data name="pasteTextMenuItem.Text" xml:space="preserve">
<value>Yapıştır</value>
</data>
<data name="executeQueryButton.Text" xml:space="preserve">
<value>İşle</value>
</data>
<data name="querySyntaxDocsButton.Text" xml:space="preserve">
<value>Sorgu Söz Dizimi</value>
</data>
<data name="querySyntaxDocsButton.ToolTip" xml:space="preserve">
<value />
</data>
<data name="statusStrip.ToolTip" xml:space="preserve">
<value />
</data>
<data name="toolStripStatusLabel1.Size" type="System.Drawing.Size, System.Drawing">
<value>63, 17</value>
</data>
<data name="toolStripStatusLabel1.Text" xml:space="preserve">
<value>Gösterilen:</value>
</data>
<data name="toolStripStatusLabel2.Size" type="System.Drawing.Size, System.Drawing">
<value>40, 17</value>
</data>
<data name="toolStripStatusLabel2.Text" xml:space="preserve">
<value>Sonuç</value>
</data>
<data name="toolStripStatusLabel4.Size" type="System.Drawing.Size, System.Drawing">
<value>637, 17</value>
</data>
<data name="zoomPercentageDropDown.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACNSURBVDhPY/j27dt/SjADiHByciILoxjw4f1HkjDJBjy/
dfL/iW5TME2WASe6Tf4fqpUCG0KWARAXmBB2waSzr/4vuPQawwB0jNWArH0v/ksvfATGhAzBMABZMzGG
oBig07ASQzM2Q0Ds1hMvMQ1A14SOQRpBGMYHuZYkA7BhkKspMgCEqWcAJZiBUgAABzX8nOIkzeMAAAAA
SUVORK5CYII=
</value>
</data>
<data name="zoomPercentageDropDown.Size" type="System.Drawing.Size, System.Drawing">
<value>120, 20</value>
</data>
<data name="zoomPercentageDropDown.Text" xml:space="preserve">
<value>Sorgu Zumu: 100%</value>
</data>
<data name="queryExecutionStatusLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>54, 17</value>
</data>
<data name="queryExecutionStatusLabel.Text" xml:space="preserve">
<value>İşleniyor:</value>
</data>
<data name="closeButton.ToolTip" xml:space="preserve">
<value />
</data>
<data name="$this.Text" xml:space="preserve">
<value>ParquetViewer - Sorgu Editörü (DuckDB Desteğiyle)</value>
</data>
<data name="$this.ToolTip" xml:space="preserve">
<value />
</data>
</root>

View file

@ -360,15 +360,6 @@ namespace ParquetViewer.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Frozen.
/// </summary>
internal static string FrozenColumnText {
get {
return ResourceManager.GetString("FrozenColumnText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Image saved to {0}.
/// </summary>

View file

@ -394,8 +394,4 @@ You can always toggle this on/off from the Edit menu.</value>
<value>Byte arrays not supported</value>
<comment>Shown when a byte[] type is in the results in the Query Editor window. As these types are currently not supported by DuckDB.</comment>
</data>
<data name="FrozenColumnText" xml:space="preserve">
<value>Frozen</value>
<comment>When the user right-clicks on a column header this is the text shown for freezing the column. Freezing a column makes it so it is always visible no matter how much you scroll horizontally.</comment>
</data>
</root>

View file

@ -333,7 +333,4 @@ Tercihinizi Düzen menüsünden istediğiniz zaman değiştirebilirsiniz.</value
<data name="ByteArraysNotSupportedErrorTitle" xml:space="preserve">
<value>Byte[] tipli sonuçlar desteklenmemektedir</value>
</data>
<data name="FrozenColumnText" xml:space="preserve">
<value>Dondur</value>
</data>
</root>