diff --git a/.gitignore b/.gitignore index 85f96d0..5570b9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,31 @@ -dist/ -**/Win32/ -**/Win64/ -**/Linux64/ -**/__history/ -**/__recovery/ -src/*.~* +# Uncomment these types if you want even more clean repository. But be careful. +# It can make harm to an existing project source. Read explanations below. + +# Resource files are binaries containing manifest, project icon and version info. +# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. *.res + +# Type library file (binary). In old Delphi versions it should be stored. +# Since Delphi 2009 it is produced from .ridl file and can safely be ignored. +#*.tlb +# +# Diagram Portfolio file. Used by the diagram editor up to Delphi 7. +# Uncomment this if you are not using diagrams or use newer Delphi version. +#*.ddp +# +# Visual LiveBindings file. Added in Delphi XE2. +# Uncomment this if you are not using LiveBindings Designer. +#*.vlb +# +# Deployment Manager configuration file for your project. Added in Delphi XE2. +# Uncomment this if it is not mobile development and you do not use remote debug feature. +#*.deployproj +# +# C++ object files produced when C/C++ Output file generation is configured. +# Uncomment this if you are not using external objects (zlib library for example). +#*.obj + +# Delphi compiler-generated binaries (safe to delete) *.exe *.dll *.bpl @@ -23,14 +43,27 @@ src/*.~* *.a *.o *.ocx + +# Delphi autogenerated files (duplicated info) +*.cfg +*.hpp +*Resource.rc + +# Delphi local files (user-specific info) *.local *.identcache *.projdata *.tvsconfig +*.skincfg *.dsk -*.dcu -*.exe -*.so + +# Delphi history and backups +__history/ +__recovery/ *.~* -*.a -*.stat \ No newline at end of file + +# Castalia statistics file (since XE7 Castalia is distributed with Delphi) +*.stat + +# Boss dependency manager vendor folder https://github.com/HashLoad/boss +modules/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index df057c6..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "modules/DataSetConverter4Delphi"] - path = modules/DataSetConverter4Delphi - url = https://github.com/hunsche/DataSetConverter4Delphi.git diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9d5c40d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 HashLoad + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2cd2dfc --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# ragna +Ragna Ragna is a query builder for projects written in Delphi, compatible with FireDAC and UniDAC components. +
We created a channel on Telegram for questions and support:

+ + + + +## ⚙️ Installation +Installation is done using the [`boss install`](https://github.com/HashLoad/boss) command: +``` sh +boss install ragna +``` +If you choose to install manually, simply add the following folders to your project, in *Project > Options > Resource Compiler > Directories and Conditionals > Include file search path* +``` +../ragna/src/core +../ragna/src/helpers +../ragna/src/interfaces +../ragna/src/state +../ragna/src/types +``` + +## ⚡️ Quickstart +You need to use Ragna +```pascal +uses Ragna; +``` + +* Open query +```delphi +begin + Country.OpenUp; +end; +``` + +* Open empty query +```delphi +begin + Country.OpenEmpty; +end; +``` + +* Where +```delphi +begin + Country + .Where(CountryName).Equals('Brazil') + .OpenUp; +end; +``` + +* Or +```delphi +begin + Country + .Where(CountryName).Equals('Brazil') + .&Or(CountryName).Equals('Canada') + .OpenUp; +end; +``` + +* And +```delphi +begin + Country + .Where(CountryName).Equals('Brazil') + .&And(CountryCapital).Equals('Brasilia') + .OpenUp; +end; +``` + +* Like +```delphi +begin + Country + .Where(CountryName).Like('B') + .OpenUp; +end; +``` + +* Order +```delphi +begin + Country + .Order(CountryName) + .OpenUp; +end; +``` + +* To JSON object +```delphi +var + LJson: TJSONObject; +begin + LJson := Country.OpenUp.ToJSONObject; +end; +``` + +* To JSON array +```delphi +var + LJson: TJSONArray; +begin + LJson := Country.OpenUp.ToJSONArray; +end; +``` + +## ⚠️ License +`Ragna` is free and open-source middleware licensed under the [MIT License](https://github.com/HashLoad/ragna/blob/master/LICENSE). diff --git a/boss-lock.json b/boss-lock.json new file mode 100644 index 0000000..fb8dd53 --- /dev/null +++ b/boss-lock.json @@ -0,0 +1,14 @@ +{ + "hash": "b14e6a77427d10f868e9622e3b2074b0", + "updated": "2022-05-03T11:38:24.2808549-03:00", + "installedModules": { + "github.com/viniciussanchez/dataset-serialize": { + "name": "dataset-serialize", + "version": "v2.4.0", + "hash": "f47b044fca0d9bb347f856798fb20cad", + "artifacts": {}, + "failed": false, + "changed": false + } + } +} \ No newline at end of file diff --git a/boss.json b/boss.json new file mode 100644 index 0000000..2652a9d --- /dev/null +++ b/boss.json @@ -0,0 +1,11 @@ +{ + "name": "ragna", + "description": "", + "version": "1.0.0", + "homepage": "", + "mainsrc": "src", + "projects": [], + "dependencies": { + "github.com/viniciussanchez/dataset-serialize": "^v2.4.0" + } +} \ No newline at end of file diff --git a/modules/DataSetConverter4Delphi b/modules/DataSetConverter4Delphi deleted file mode 160000 index 196f36c..0000000 --- a/modules/DataSetConverter4Delphi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 196f36cb9501784a4277453c318df90a67407d20 diff --git a/ragna.dpk b/ragna.dpk new file mode 100644 index 0000000..69da73c --- /dev/null +++ b/ragna.dpk @@ -0,0 +1,47 @@ +package ragna; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + dbrtl, + FireDAC, + FireDACCommonDriver, + FireDACCommon; + +contains + Ragna.Intf in 'src\interfaces\Ragna.Intf.pas', + Ragna.Criteria.Intf in 'src\interfaces\Ragna.Criteria.Intf.pas', + Ragna.Criteria.Impl in 'src\core\Ragna.Criteria.Impl.pas', + Ragna.Impl in 'src\core\Ragna.Impl.pas', + Ragna in 'src\helpers\Ragna.pas', + Ragna.State in 'src\state\Ragna.State.pas', + Ragna.Types in 'src\types\Ragna.Types.pas'; + +end. diff --git a/ragna.dproj b/ragna.dproj new file mode 100644 index 0000000..72a5d96 --- /dev/null +++ b/ragna.dproj @@ -0,0 +1,950 @@ + + + {D9E8CA95-FBB1-42EA-A7B4-909AC5ACFADD} + ragna.dpk + 19.5 + None + True + Debug + Win32 + 1 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + All + true + ragna + modules\.dcp;modules\.dcu;modules;modules\dataset-serialize\src;$(DCC_UnitSearchPath) + + + None + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services-ads-7.0.0.dex.jar;google-play-services-analytics-7.0.0.dex.jar;google-play-services-base-7.0.0.dex.jar;google-play-services-identity-7.0.0.dex.jar;google-play-services-maps-7.0.0.dex.jar;google-play-services-panorama-7.0.0.dex.jar;google-play-services-plus-7.0.0.dex.jar;google-play-services-wallet-7.0.0.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + true + Base + true + None + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services-ads-7.0.0.dex.jar;google-play-services-analytics-7.0.0.dex.jar;google-play-services-base-7.0.0.dex.jar;google-play-services-identity-7.0.0.dex.jar;google-play-services-maps-7.0.0.dex.jar;google-play-services-panorama-7.0.0.dex.jar;google-play-services-plus-7.0.0.dex.jar;google-play-services-wallet-7.0.0.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + iPhoneAndiPad + true + Debug + $(MSBuildProjectName) + + + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + iPhoneAndiPad + true + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false + Debug + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false + Debug + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Package + + + + Embarcadero DBExpress DataSnap Native Server Components + ExpressPivotGrid OLAP by Developer Express Inc. + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + ragna.dpk + + + + + + + true + + + + + true + + + + + + true + + + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + False + False + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/ragna.res b/ragna.res new file mode 100644 index 0000000..d07df7c Binary files /dev/null and b/ragna.res differ diff --git a/samples/Samples.dpr b/samples/Samples.dpr new file mode 100644 index 0000000..bb547e0 --- /dev/null +++ b/samples/Samples.dpr @@ -0,0 +1,21 @@ +program Samples; + +uses + Vcl.Forms, + Views.Samples in 'src\Views.Samples.pas' {FrmRagnaSamples}, + Ragna.Criteria.Impl in '..\src\core\Ragna.Criteria.Impl.pas', + Ragna.Impl in '..\src\core\Ragna.Impl.pas', + Ragna in '..\src\helpers\Ragna.pas', + Ragna.Criteria.Intf in '..\src\interfaces\Ragna.Criteria.Intf.pas', + Ragna.Intf in '..\src\interfaces\Ragna.Intf.pas', + Ragna.State in '..\src\state\Ragna.State.pas', + Ragna.Types in '..\src\types\Ragna.Types.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TFrmRagnaSamples, FrmRagnaSamples); + Application.Run; +end. diff --git a/samples/Samples.dproj b/samples/Samples.dproj new file mode 100644 index 0000000..b24c3f5 --- /dev/null +++ b/samples/Samples.dproj @@ -0,0 +1,1246 @@ + + + {4FF886E7-EF89-4410-871B-B4283C20426D} + 19.4 + VCL + Samples.dpr + True + Debug + Win32 + 1 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + Samples + + + DBXSqliteDriver;dxFlowChartRS26;dxPSdxMapControlLnkRS26;DBXDb2Driver;vclactnband;dxBarRS26;vclFireDAC;dxFireDACEMFRS26;tethering;dxSpreadSheetInplaceRichEditRS26;FireDACADSDriver;dxSkinVisualStudio2013BlueRS26;dxRichEditCoreRS26;dxPSdxSpreadSheetLnkRS26;dxSkinSharpPlusRS26;FireDACMSSQLDriver;vcltouch;vcldb;svn;dxPSTeeChartRS26;dxSkinFoggyRS26;dxSkinVisualStudio2013DarkRS26;dxSkinOffice2013DarkGrayRS26;dxGDIPlusRS26;dxAuthorizationAgentsRS26;dxPSdxFCLnkRS26;vclib;frxTee26;dxPSLnksRS26;FireDACDBXDriver;cxGridRS26;dxPsPrVwAdvRS26;dxPDFViewerRS26;dxSkinSpringTimeRS26;boss_ide;vclx;dxPScxTLLnkRS26;dxSkinOffice2010BlueRS26;RESTBackendComponents;dxSkinOffice2016DarkRS26;VCLRESTComponents;dxSkinMoneyTwinsRS26;dxSkinOffice2016ColorfulRS26;fsTee26;dxSkinValentineRS26;dxSkinHighContrastRS26;vclie;bindengine;CloudService;dxmdsRS26;FireDACMySQLDriver;fsIBX26;frx26;dxdborRS26;DataSnapClient;dxSkinOffice2013WhiteRS26;dxFireDACServerModeRS26;bindcompdbx;fsFD26;DBXSybaseASEDriver;IndyIPServer;cxPivotGridRS26;IndySystem;fsADO26;frxDBX26;dxSkinDarkRoomRS26;cxTreeListdxBarPopupMenuRS26;dsnapcon;cxTreeListRS26;dxPScxPivotGridLnkRS26;cxSchedulerRibbonStyleEventEditorRS26;dxPSCoreRS26;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;dxSpreadSheetRS26;dxBarExtItemsRS26;dxPSdxGaugeControlLnkRS26;emshosting;dxSkinLondonLiquidSkyRS26;DBXOdbcDriver;FireDACTDataDriver;FMXTee;dxdbtrRS26;dxRichEditControlCoreRS26;soaprtl;DbxCommonDriver;dxFlowChartAdvancedCustomizeFormRS26;dxSkinLiquidSkyRS26;dxSkinSevenRS26;dxDockingRS26;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;cxLibraryRS26;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;cxDataRS26;dxPScxSchedulerLnkRS26;dxSpreadSheetConditionalFormattingDialogsRS26;appanalytics;dxRibbonCustomizationFormRS26;cxSchedulerGridRS26;IndyIPClient;bindcompvcl;dxSkinVisualStudio2013LightRS26;TeeUI;dxADOEMFRS26;VclSmp;FireDACODBCDriver;dxRibbonRS26;DataSnapIndy10ServerTransport;dxPScxCommonRS26;dxRichEditDocumentModelRS26;DataSnapProviderClient;FireDACMongoDBDriver;dxPScxGridLnkRS26;dxSkinDevExpressDarkStyleRS26;dxSpreadSheetCoreRS26;RESTComponents;dxSkinGlassOceansRS26;DBXInterBaseDriver;dxPScxExtCommonRS26;dxSkinPumpkinRS26;emsclientfiredac;dxSkinXmas2008BlueRS26;DataSnapFireDAC;svnui;frxFD26;dxSkinOffice2007SilverRS26;cxPageControlRS26;dxSkinTheBezierRS26;dxSkinDevExpressStyleRS26;DBXMSSQLDriver;dxRichEditControlRS26;DatasnapConnectorsFreePascal;dxGaugeControlRS26;dxorgcRS26;dxPScxVGridLnkRS26;bindcompfmx;dxSkinOffice2007PinkRS26;DBXOracleDriver;inetdb;dxSkinOffice2007BlueRS26;dxSkinStardustRS26;CEF4Delphi;dxBarDBNavRS26;dxDBXServerModeRS26;dxSkinTheAsphaltWorldRS26;dxSkinSilverRS26;FmxTeeUI;emsedge;dxLayoutControlRS26;fmx;FireDACIBDriver;fmxdae;dxServerModeRS26;dxWizardControlRS26;dxSkinBlueprintRS26;dxSkiniMaginaryRS26;dxTabbedMDIRS26;fs26;dxEMFRS26;dbexpress;IndyCore;dxComnRS26;frxIntIO26;dsnap;emsclient;DataSnapCommon;dxSkinSharpRS26;FireDACCommon;DataSnapConnectors;cxSchedulerTreeBrowserRS26;dxADOServerModeRS26;soapserver;dxSkinOffice2007BlackRS26;cxVerticalGridRS26;dxtrmdRS26;FireDACOracleDriver;DBXMySQLDriver;cxEditorsRS26;cxSchedulerRS26;cxSchedulerWebServiceStorageRS26;DBXFirebirdDriver;dxSkinMetropolisDarkRS26;dxSkinOffice2010BlackRS26;dxPSdxLCLnkRS26;FireDACCommonODBC;FireDACCommonDriver;dxMapControlRS26;dxSkinBlackRS26;dxSkinOffice2013LightGrayRS26;frxIntIOIndy26;inet;dxSpellCheckerRS26;dxSkinCoffeeRS26;IndyIPCommon;dxSpreadSheetCoreConditionalFormattingDialogsRS26;vcl;dxPSdxDBOCLnkRS26;frxDB26;dxSkinMetropolisRS26;FireDACDb2Driver;dxSpreadSheetReportDesignerRS26;dxPScxPCProdRS26;dxNavBarRS26;fsDB26;dxCoreRS26;cxExportRS26;TeeDB;FireDAC;dxThemeRS26;dxHttpIndyRequestRS26;dxPSPrVwRibbonRS26;dxSkinOffice2010SilverRS26;frxe26;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;dxSkinSevenClassicRS26;cxPivotGridChartRS26;dxPSRichEditControlLnkRS26;frxIBX26;dxPSDBTeeChartRS26;ibxpress;Tee;DataSnapServer;ibxbindings;dxPSdxDBTVLnkRS26;vclwinx;FireDACDSDriver;frxADO26;dxOfficeCoreRS26;dxTileControlRS26;dxSkinsCoreRS26;CustomIPTransport;vcldsnap;DOSCommandDR;bindcomp;dxSkinLilianRS26;dxSkinSummer2008RS26;DBXInformixDriver;dxPSdxOCLnkRS26;dxSkinVS2010RS26;dxSkinBlueRS26;dmvcframeworkRT;dbxcds;adortl;dxSkinMcSkinRS26;dxSkinDarkSideRS26;dmvcframeworkDT;dxSpreadSheetCoreDialogsRS26;dxBarExtDBItemsRS26;dsnapxml;dbrtl;IndyProtocols;inetdbxpress;dxSkinOffice2007GreenRS26;dxRichEditInplaceRS26;dxSkinWhiteprintRS26;dxPSdxPDFViewerLnkRS26;dxSkinCaramelRS26;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DBXSqliteDriver;dxFlowChartRS26;dxPSdxMapControlLnkRS26;DBXDb2Driver;vclactnband;dxBarRS26;vclFireDAC;dxFireDACEMFRS26;tethering;dxSpreadSheetInplaceRichEditRS26;FireDACADSDriver;dxSkinVisualStudio2013BlueRS26;dxRichEditCoreRS26;dxPSdxSpreadSheetLnkRS26;dxSkinSharpPlusRS26;FireDACMSSQLDriver;vcltouch;vcldb;dxPSTeeChartRS26;dxSkinFoggyRS26;dxSkinVisualStudio2013DarkRS26;dxSkinOffice2013DarkGrayRS26;dxGDIPlusRS26;dxAuthorizationAgentsRS26;dxPSdxFCLnkRS26;vclib;dxPSLnksRS26;FireDACDBXDriver;cxGridRS26;dxPsPrVwAdvRS26;dxPDFViewerRS26;dxSkinSpringTimeRS26;vclx;dxPScxTLLnkRS26;dxSkinOffice2010BlueRS26;RESTBackendComponents;dxSkinOffice2016DarkRS26;VCLRESTComponents;dxSkinMoneyTwinsRS26;dxSkinOffice2016ColorfulRS26;dxSkinValentineRS26;dxSkinHighContrastRS26;vclie;bindengine;CloudService;dxmdsRS26;FireDACMySQLDriver;dxdborRS26;DataSnapClient;dxSkinOffice2013WhiteRS26;dxFireDACServerModeRS26;bindcompdbx;DBXSybaseASEDriver;IndyIPServer;cxPivotGridRS26;IndySystem;dxSkinDarkRoomRS26;cxTreeListdxBarPopupMenuRS26;dsnapcon;cxTreeListRS26;dxPScxPivotGridLnkRS26;cxSchedulerRibbonStyleEventEditorRS26;dxPSCoreRS26;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;dxSpreadSheetRS26;dxBarExtItemsRS26;dxPSdxGaugeControlLnkRS26;emshosting;dxSkinLondonLiquidSkyRS26;DBXOdbcDriver;FireDACTDataDriver;FMXTee;dxdbtrRS26;dxRichEditControlCoreRS26;soaprtl;DbxCommonDriver;dxFlowChartAdvancedCustomizeFormRS26;dxSkinLiquidSkyRS26;dxSkinSevenRS26;dxDockingRS26;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;cxLibraryRS26;rtl;emsserverresource;DbxClientDriver;DBXSybaseASADriver;cxDataRS26;dxPScxSchedulerLnkRS26;dxSpreadSheetConditionalFormattingDialogsRS26;appanalytics;dxRibbonCustomizationFormRS26;cxSchedulerGridRS26;IndyIPClient;bindcompvcl;dxSkinVisualStudio2013LightRS26;TeeUI;dxADOEMFRS26;VclSmp;FireDACODBCDriver;dxRibbonRS26;DataSnapIndy10ServerTransport;dxPScxCommonRS26;dxRichEditDocumentModelRS26;DataSnapProviderClient;FireDACMongoDBDriver;dxPScxGridLnkRS26;dxSkinDevExpressDarkStyleRS26;dxSpreadSheetCoreRS26;RESTComponents;dxSkinGlassOceansRS26;DBXInterBaseDriver;dxPScxExtCommonRS26;dxSkinPumpkinRS26;emsclientfiredac;dxSkinXmas2008BlueRS26;DataSnapFireDAC;dxSkinOffice2007SilverRS26;cxPageControlRS26;dxSkinTheBezierRS26;dxSkinDevExpressStyleRS26;DBXMSSQLDriver;dxRichEditControlRS26;DatasnapConnectorsFreePascal;dxGaugeControlRS26;dxorgcRS26;dxPScxVGridLnkRS26;bindcompfmx;dxSkinOffice2007PinkRS26;DBXOracleDriver;inetdb;dxSkinOffice2007BlueRS26;dxSkinStardustRS26;CEF4Delphi;dxBarDBNavRS26;dxDBXServerModeRS26;dxSkinTheAsphaltWorldRS26;dxSkinSilverRS26;FmxTeeUI;emsedge;dxLayoutControlRS26;fmx;FireDACIBDriver;fmxdae;dxServerModeRS26;dxWizardControlRS26;dxSkinBlueprintRS26;dxSkiniMaginaryRS26;dxTabbedMDIRS26;dxEMFRS26;dbexpress;IndyCore;dxComnRS26;dsnap;emsclient;DataSnapCommon;dxSkinSharpRS26;FireDACCommon;DataSnapConnectors;cxSchedulerTreeBrowserRS26;dxADOServerModeRS26;soapserver;dxSkinOffice2007BlackRS26;cxVerticalGridRS26;dxtrmdRS26;FireDACOracleDriver;DBXMySQLDriver;cxEditorsRS26;cxSchedulerRS26;cxSchedulerWebServiceStorageRS26;DBXFirebirdDriver;dxSkinMetropolisDarkRS26;dxSkinOffice2010BlackRS26;dxPSdxLCLnkRS26;FireDACCommonODBC;FireDACCommonDriver;dxMapControlRS26;dxSkinBlackRS26;dxSkinOffice2013LightGrayRS26;inet;dxSpellCheckerRS26;dxSkinCoffeeRS26;IndyIPCommon;dxSpreadSheetCoreConditionalFormattingDialogsRS26;vcl;dxPSdxDBOCLnkRS26;dxSkinMetropolisRS26;FireDACDb2Driver;dxSpreadSheetReportDesignerRS26;dxPScxPCProdRS26;dxNavBarRS26;dxCoreRS26;cxExportRS26;TeeDB;FireDAC;dxThemeRS26;dxHttpIndyRequestRS26;dxPSPrVwRibbonRS26;dxSkinOffice2010SilverRS26;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;dxSkinSevenClassicRS26;cxPivotGridChartRS26;dxPSRichEditControlLnkRS26;dxPSDBTeeChartRS26;ibxpress;Tee;DataSnapServer;ibxbindings;dxPSdxDBTVLnkRS26;vclwinx;FireDACDSDriver;dxOfficeCoreRS26;dxTileControlRS26;dxSkinsCoreRS26;CustomIPTransport;vcldsnap;DOSCommandDR;bindcomp;dxSkinLilianRS26;dxSkinSummer2008RS26;DBXInformixDriver;dxPSdxOCLnkRS26;dxSkinVS2010RS26;dxSkinBlueRS26;dbxcds;adortl;dxSkinMcSkinRS26;dxSkinDarkSideRS26;dxSpreadSheetCoreDialogsRS26;dxBarExtDBItemsRS26;dsnapxml;dbrtl;IndyProtocols;inetdbxpress;dxSkinOffice2007GreenRS26;dxRichEditInplaceRS26;dxSkinWhiteprintRS26;dxPSdxPDFViewerLnkRS26;dxSkinCaramelRS26;fmxase;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + PerMonitorV2 + ..\modules\dataset-serialize\src;$(DCC_UnitSearchPath) + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + PerMonitorV2 + + + + MainSource + + +
FrmRagnaSamples
+ dfm +
+ + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + Samples.dpr + + + + + + Samples.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + True + False + + + 12 + + + + +
diff --git a/samples/criteria/Samples.Criteria.dfm b/samples/criteria/Samples.Criteria.dfm deleted file mode 100644 index ff2db7d..0000000 --- a/samples/criteria/Samples.Criteria.dfm +++ /dev/null @@ -1,16 +0,0 @@ -object SampleCriteria: TSampleCriteria - Left = 0 - Top = 0 - Caption = 'SampleCriteria' - ClientHeight = 231 - ClientWidth = 505 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - OldCreateOrder = False - PixelsPerInch = 96 - TextHeight = 13 -end diff --git a/samples/criteria/Samples.Criteria.pas b/samples/criteria/Samples.Criteria.pas deleted file mode 100644 index 16adfe3..0000000 --- a/samples/criteria/Samples.Criteria.pas +++ /dev/null @@ -1,30 +0,0 @@ -unit Samples.Criteria; - -interface - -uses - Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, - System.Classes, Vcl.Graphics, - Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option, - FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, - FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, Data.DB, - FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.UI.Intf, FireDAC.Stan.Def, - FireDAC.Stan.Pool, FireDAC.Phys, FireDAC.VCLUI.Wait, FireDAC.Phys.PG, - FireDAC.Phys.PGDef; - -type - TSampleCriteria = class(TForm) - private - { Private declarations } - public - { Public declarations } - end; - -var - SampleCriteria: TSampleCriteria; - -implementation - -{$R *.dfm} - -end. diff --git a/samples/criteria/criteria.dpr b/samples/criteria/criteria.dpr deleted file mode 100644 index 625a4ae..0000000 --- a/samples/criteria/criteria.dpr +++ /dev/null @@ -1,23 +0,0 @@ -program criteria; - -uses - Vcl.Forms, - Samples.Criteria in 'Samples.Criteria.pas' {SampleCriteria}, - Ragna.Criteria in '..\..\src\Ragna.Criteria.pas', - Ragna in '..\..\src\Ragna.pas', - Ragna.Impl in '..\..\src\Ragna.Impl.pas', - Ragna.State in '..\..\src\Ragna.State.pas', - DataSetConverter4D.Helper in '..\..\modules\DataSetConverter4Delphi\src\DataSetConverter4D.Helper.pas', - DataSetConverter4D.Impl in '..\..\modules\DataSetConverter4Delphi\src\DataSetConverter4D.Impl.pas', - DataSetConverter4D in '..\..\modules\DataSetConverter4Delphi\src\DataSetConverter4D.pas', - DataSetConverter4D.Util in '..\..\modules\DataSetConverter4Delphi\src\DataSetConverter4D.Util.pas', - Ragna.Intf in '..\..\src\Ragna.Intf.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.MainFormOnTaskbar := True; - Application.CreateForm(TSampleCriteria, SampleCriteria); - Application.Run; -end. diff --git a/samples/criteria/criteria.dproj b/samples/criteria/criteria.dproj deleted file mode 100644 index 7d7a37e..0000000 --- a/samples/criteria/criteria.dproj +++ /dev/null @@ -1,569 +0,0 @@ - - - {36E01FA2-146E-4719-B53E-F5CBEFDF21C5} - 18.4 - VCL - criteria.dpr - True - Debug - Win32 - 1 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - .\$(Platform)\$(Config) - .\$(Platform)\$(Config) - false - false - false - false - false - RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - criteria - - - DBXSqliteDriver;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;tethering;svnui;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;emshosting;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - $(BDS)\bin\default_app.manifest - - - DBXSqliteDriver;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;inetdb;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;emshosting;FireDACPgDriver;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) - - - DEBUG;$(DCC_Define) - true - false - true - true - true - - - false - true - true - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - true - true - - - - MainSource - - -
SampleCriteria
- dfm -
- - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - Delphi.Personality.12 - Application - - - - criteria.dpr - - - - - - criteria.exe - true - - - - - 1 - - - Contents\MacOS - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - Contents\MacOS - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - Contents\Resources\StartUp\ - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 1 - - - 1 - - - - - ..\ - 1 - - - ..\ - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\ - 1 - - - - - Contents - 1 - - - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - True - False - - - 12 - - - - -
diff --git a/samples/src/Views.Samples.dfm b/samples/src/Views.Samples.dfm new file mode 100644 index 0000000..d0aa4c3 --- /dev/null +++ b/samples/src/Views.Samples.dfm @@ -0,0 +1,175 @@ +object FrmRagnaSamples: TFrmRagnaSamples + Left = 0 + Top = 0 + Caption = 'Ragna samples' + ClientHeight = 442 + ClientWidth = 658 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 + object DBGrid1: TDBGrid + Left = 0 + Top = 208 + Width = 658 + Height = 234 + Align = alBottom + DataSource = dsCountry + TabOrder = 0 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + end + object Button1: TButton + Left = 24 + Top = 16 + Width = 75 + Height = 25 + Caption = 'Open' + TabOrder = 1 + OnClick = Button1Click + end + object Button2: TButton + Left = 24 + Top = 47 + Width = 75 + Height = 25 + Caption = 'Open empty' + TabOrder = 2 + OnClick = Button2Click + end + object Button3: TButton + Left = 24 + Top = 78 + Width = 75 + Height = 25 + Caption = 'Or' + TabOrder = 3 + OnClick = Button3Click + end + object Button4: TButton + Left = 105 + Top = 78 + Width = 75 + Height = 25 + Caption = 'And' + TabOrder = 4 + OnClick = Button4Click + end + object Button5: TButton + Left = 186 + Top = 78 + Width = 75 + Height = 25 + Caption = 'Like' + TabOrder = 5 + OnClick = Button5Click + end + object Button6: TButton + Left = 267 + Top = 78 + Width = 75 + Height = 25 + Caption = 'Order' + TabOrder = 6 + OnClick = Button6Click + end + object mmJson: TMemo + Left = 0 + Top = 119 + Width = 658 + Height = 89 + Align = alBottom + TabOrder = 7 + ExplicitLeft = 465 + ExplicitTop = 8 + ExplicitWidth = 185 + end + object Button7: TButton + Left = 105 + Top = 47 + Width = 75 + Height = 25 + Caption = 'JSON Object' + TabOrder = 8 + OnClick = Button7Click + end + object Button8: TButton + Left = 186 + Top = 47 + Width = 75 + Height = 25 + Caption = 'JSON Array' + TabOrder = 9 + OnClick = Button8Click + end + object Button9: TButton + Left = 267 + Top = 47 + Width = 75 + Height = 25 + Caption = 'Append' + TabOrder = 10 + OnClick = Button9Click + end + object Button10: TButton + Left = 348 + Top = 47 + Width = 75 + Height = 25 + Caption = 'Edit' + TabOrder = 11 + OnClick = Button10Click + end + object dsCountry: TDataSource + DataSet = Country + Left = 304 + Top = 240 + end + object Country: TFDQuery + Connection = FDConnection + SQL.Strings = ( + 'select * from country') + Left = 344 + Top = 240 + object CountryName: TWideStringField + FieldName = 'Name' + Origin = 'Name' + ProviderFlags = [pfInUpdate, pfInWhere, pfInKey] + Size = 24 + end + object CountryCapital: TWideStringField + FieldName = 'Capital' + Origin = 'Capital' + Size = 24 + end + object CountryContinent: TWideStringField + FieldName = 'Continent' + Origin = 'Continent' + Size = 24 + end + object CountryArea: TFloatField + FieldName = 'Area' + Origin = 'Area' + end + object CountryPopulation: TFloatField + FieldName = 'Population' + Origin = 'Population' + end + end + object FDConnection: TFDConnection + Params.Strings = ( + 'ConnectionDef=DBDEMOS') + Connected = True + LoginPrompt = False + Left = 384 + Top = 240 + end +end diff --git a/samples/src/Views.Samples.pas b/samples/src/Views.Samples.pas new file mode 100644 index 0000000..2c6b1c0 --- /dev/null +++ b/samples/src/Views.Samples.pas @@ -0,0 +1,116 @@ +unit Views.Samples; + +interface + +uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, + Vcl.Dialogs, Data.DB, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, + FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.Grids, + Vcl.DBGrids, FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys, FireDAC.Phys.MSAcc, FireDAC.Phys.MSAccDef, + FireDAC.VCLUI.Wait, Vcl.StdCtrls, FireDAC.Phys.IB, FireDAC.Phys.IBDef; + +type + TFrmRagnaSamples = class(TForm) + DBGrid1: TDBGrid; + dsCountry: TDataSource; + Country: TFDQuery; + Button1: TButton; + FDConnection: TFDConnection; + CountryName: TWideStringField; + CountryCapital: TWideStringField; + CountryContinent: TWideStringField; + CountryArea: TFloatField; + CountryPopulation: TFloatField; + Button2: TButton; + Button3: TButton; + Button4: TButton; + Button5: TButton; + Button6: TButton; + mmJson: TMemo; + Button7: TButton; + Button8: TButton; + Button9: TButton; + Button10: TButton; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure Button6Click(Sender: TObject); + procedure Button5Click(Sender: TObject); + procedure Button8Click(Sender: TObject); + procedure Button7Click(Sender: TObject); + procedure Button9Click(Sender: TObject); + procedure Button10Click(Sender: TObject); + end; + +var + FrmRagnaSamples: TFrmRagnaSamples; + +implementation + +{$R *.dfm} + +uses Ragna; + +procedure TFrmRagnaSamples.Button10Click(Sender: TObject); +begin + Country + .OpenUp + .EditFromJson('{"name":"A","capital":"B","continent":"C","area":1,"population":2}'); +end; + +procedure TFrmRagnaSamples.Button1Click(Sender: TObject); +begin + Country.OpenUp; +end; + +procedure TFrmRagnaSamples.Button2Click(Sender: TObject); +begin + Country.OpenEmpty; +end; + +procedure TFrmRagnaSamples.Button3Click(Sender: TObject); +begin + Country + .Where(CountryName).Equals('Brazil') + .&Or(CountryName).Equals('Canada') + .OpenUp; +end; + +procedure TFrmRagnaSamples.Button4Click(Sender: TObject); +begin + Country + .Where(CountryName).Equals('Brazil') + .&And(CountryCapital).Equals('Brasilia') + .OpenUp; +end; + +procedure TFrmRagnaSamples.Button5Click(Sender: TObject); +begin + Country + .Where(CountryName).Like('B') + .OpenUp; +end; + +procedure TFrmRagnaSamples.Button6Click(Sender: TObject); +begin + Country + .Order(CountryName) + .OpenUp; +end; + +procedure TFrmRagnaSamples.Button7Click(Sender: TObject); +begin + mmJson.Lines.Text := Country.OpenUp.ToJSONObject.ToString; +end; + +procedure TFrmRagnaSamples.Button8Click(Sender: TObject); +begin + mmJson.Lines.Text := Country.OpenUp.ToJSONArray.ToString; +end; + +procedure TFrmRagnaSamples.Button9Click(Sender: TObject); +begin + Country.New('{"name":"A","capital":"B","continent":"C","area":1,"population":2}'); +end; + +end. diff --git a/src/Ragna.Criteria.pas b/src/Ragna.Criteria.pas deleted file mode 100644 index 9e9d3f9..0000000 --- a/src/Ragna.Criteria.pas +++ /dev/null @@ -1,169 +0,0 @@ -unit Ragna.Criteria; - -interface - -uses - FireDAC.Comp.Client, StrUtils, Ragna.Intf, Data.DB, FireDAC.Stan.Param, - System.Hash; - -type - - TOperatorType = (otWhere, otOr, otLike, otEquals, otOrder, otAnd); - - TPGCriteria = class(TInterfacedObject, ICriteria) - const - OPERATORS: array [low(TOperatorType) .. High(TOperatorType) - ] of string = ('WHERE', 'OR', 'LIKE', '=', 'ORDER BY', 'AND'); - private - FQuery: TFDQuery; - public - procedure Where(AField: string); overload; - procedure Where(AField: TField); overload; - procedure Where(AValue: Boolean); overload; - procedure &Or(AField: string); overload; - procedure &Or(AField: TField); overload; - procedure &And(AField: string); overload; - procedure &And(AField: TField); overload; - procedure Like(AValue: string); - procedure &Equals(AValue: Int64); overload; - procedure &Equals(AValue: Boolean); overload; - procedure Order(AField: TField); - constructor Create(AQuery: TFDQuery); - end; - - TManagerCriteria = class - private - FCriteria: ICriteria; - function GetInstanceCriteria(AQuery: TFDQuery): ICriteria; - public - constructor Create(AQuery: TFDQuery); - destructor Destroy; override; - property Criteria: ICriteria read FCriteria write FCriteria; - end; - -implementation - -uses SysUtils; - -{ TPGCriteria } - -procedure TPGCriteria.&And(AField: string); -const - PHRASE = ' %s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otAnd], AField])); -end; - -procedure TPGCriteria.&And(AField: TField); -const - PHRASE = ' %s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otAnd], AField.Origin])); -end; - -procedure TPGCriteria.&Or(AField: string); -const - PHRASE = ' %s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otOr], AField])); -end; - -constructor TPGCriteria.Create(AQuery: TFDQuery); -begin - FQuery := AQuery; -end; - -procedure TPGCriteria.Equals(AValue: Int64); -const - PHRASE = '%s %d'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otEquals], AValue])); -end; - -procedure TPGCriteria.Where(AField: TField); -const - PHRASE = '%s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otWhere], AField.Origin])); -end; - -procedure TPGCriteria.Equals(AValue: Boolean); -const - PHRASE = '%s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otEquals], BoolToStr(AValue, - True)])); -end; - -procedure TPGCriteria.Like(AValue: string); -const - PHRASE = '::text %s %s'; -var - LKeyParam: string; - LParam: TFDParam; -begin - LKeyParam := THashMD5.Create.HashAsString; - FQuery.SQL.Text := FQuery.SQL.Text + - format(PHRASE, [OPERATORS[otLike], ':' + LKeyParam]); - LParam := FQuery.ParamByName(LKeyParam); - LParam.DataType := ftString; - LParam.Value := AValue; -end; - -procedure TPGCriteria.Order(AField: TField); -const - PHRASE = '%s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otOrder], AField.Origin])); -end; - -procedure TPGCriteria.Where(AField: string); -const - PHRASE = '%s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otWhere], AField])); -end; - -procedure TPGCriteria.Where(AValue: Boolean); -const - PHRASE = '%s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otWhere], BoolToStr(AValue, True)])); -end; - -procedure TPGCriteria.&Or(AField: TField); -const - PHRASE = ' %s %s'; -begin - FQuery.SQL.Add(format(PHRASE, [OPERATORS[otOr], AField.Origin])); -end; - -{ TCriteria } - -constructor TManagerCriteria.Create(AQuery: TFDQuery); -begin - FCriteria := GetInstanceCriteria(AQuery); -end; - -destructor TManagerCriteria.Destroy; -begin - inherited; -end; - -function TManagerCriteria.GetInstanceCriteria(AQuery: TFDQuery): ICriteria; -var - LCriteria: ICriteria; -begin - LCriteria := nil; - - case AnsiIndexStr(AQuery.Connection.DriverName, ['PG']) of - 0: - LCriteria := TPGCriteria.Create(AQuery); - else - raise Exception.Create('Driver not suported'); - end; - - Result := LCriteria; -end; - -end. diff --git a/src/Ragna.Impl.pas b/src/Ragna.Impl.pas deleted file mode 100644 index c37dd69..0000000 --- a/src/Ragna.Impl.pas +++ /dev/null @@ -1,205 +0,0 @@ -unit Ragna.Impl; - -interface - -uses Ragna.Intf, FireDAC.Comp.Client, System.JSON, Data.DB, Ragna.Criteria, - DataSetConverter4D.Helper; - -type - - TRagna = class(TInterfacedObject, IRagna) - private - FQuery: TFDQuery; - FManagerCriteria: TManagerCriteria; - FCriteria: ICriteria; - private - function GetTableName: string; - function HasField(AFields: array of TField): Boolean; - procedure OpenEmpty; - procedure RaiseNotFound; - public - procedure Paginate(AOffSet, ALimit: integer); - procedure RadicalResearch(AValue: string; AFields: array of TField); - procedure Delete(AField: TField; AValue: Int64); - procedure FindById(AField: TField; AValue: Int64); - procedure UpdateById(AField: TField; AValue: Int64; ABody: TJSONObject); - procedure New(ABody: TJSONObject); - procedure OpenUp; - procedure StartCriteria; - procedure EndCriteria; - procedure ToJson(out AJSON: TJSONArray); overload; - procedure ToJson(out AJSON: TJSONObject); overload; - procedure EditFromJson(const AJSON: TJSONObject); - constructor Create(AQuery: TFDQuery); - destructor Destroy; - property Query: TFDQuery read FQuery write FQuery; - property Criteria: ICriteria read FCriteria write FCriteria; - end; - -implementation - -{ TRagna } - -uses Ragna.State, System.SysUtils, Ragna; - -constructor TRagna.Create(AQuery: TFDQuery); -begin - FQuery := AQuery; - FManagerCriteria := TManagerCriteria.Create(FQuery); - FCriteria := FManagerCriteria.Criteria; -end; - -procedure TRagna.Delete(AField: TField; AValue: Int64); -const - DELETE_SQL = 'DELETE FROM %s WHERE %s = :ID'; - DELETED: array [0 .. 1] of Boolean = (False, True); -var - LDeleted: integer; - LSql: string; -begin - OpenEmpty; - LSql := Format(DELETE_SQL, [GetTableName, AField.FieldName]); - LDeleted := FQuery.Connection.ExecSQL(LSql, [AValue]); - if not DELETED[LDeleted] then - RaiseNotFound; -end; - -destructor TRagna.Destroy; -begin - FManagerCriteria.Free; -end; - -procedure TRagna.EndCriteria; -var - LKey: Pointer; - LRagnaState: TRagnaState; -begin - LKey := @FQuery; - LRagnaState := TRagnaState.GetInstance; - FQuery.SQL.Text := LRagnaState.RemoveState(LKey); -end; - -procedure TRagna.FindById(AField: TField; AValue: Int64); -var - LField: string; -begin - FQuery.StartCriteria; - try - OpenEmpty; - LField := GetTableName + '.' + AField.Origin; - finally - FQuery.EndCriteria; - end; - - FQuery - .Where(LField) - .Equals(AValue); -end; - -procedure TRagna.EditFromJson(const AJSON: TJSONObject); -begin - FQuery.RecordFromJSONObject(AJSON); -end; - -function TRagna.GetTableName: string; -begin - Result := FQuery.Table.Table.SourceName; -end; - -function TRagna.HasField(AFields: array of TField): Boolean; -begin - Result := Length(AFields) > 0; -end; - -procedure TRagna.OpenUp; -begin - FQuery.Open; -end; - -procedure TRagna.OpenEmpty; -begin - FQuery.Where(True).Equals(False).OpenUp; -end; - -procedure TRagna.Paginate(AOffSet, ALimit: integer); -begin - if AOffSet > 0 then - FQuery.FetchOptions.RecsSkip := AOffSet; - - if ALimit > 0 then - FQuery.FetchOptions.RecsMax := ALimit; -end; - -procedure TRagna.New(ABody: TJSONObject); -begin - OpenEmpty; - FQuery.EditFromJson(ABody); -end; - -procedure TRagna.RadicalResearch(AValue: string; AFields: array of TField); -var - LSearch: string; - LCount: integer; -begin - if HasField(AFields) and not AValue.IsEmpty then - begin - LSearch := '%' + AValue + '%'; - - FQuery - .Where(AFields[0]) - .Like(LSearch); - - if ((Length(AFields) - 1) >= 2) then - begin - for LCount := 1 to Length(AFields) - 1 do - begin - FQuery - .&Or(AFields[LCount]) - .Like(LSearch); - end; - end; - end; -end; - -procedure TRagna.RaiseNotFound; -begin - raise Exception.Create('Resource not found!'); -end; - -procedure TRagna.StartCriteria; -var - LKey: Pointer; - LRagnaState: TRagnaState; -begin - LKey := @FQuery; - LRagnaState := TRagnaState.GetInstance; - - if LRagnaState.GetState(LKey).IsEmpty then - LRagnaState.SetState(LKey, FQuery.SQL.Text) -end; - -procedure TRagna.ToJson(out AJSON: TJSONObject); -begin - if FQuery.IsEmpty then - RaiseNotFound; - - AJSON := FQuery.AsJSONObject; -end; - -procedure TRagna.ToJson(out AJSON: TJSONArray); -begin - if FQuery.IsEmpty then - AJSON := TJSONArray.Create - else - AJSON := FQuery.AsJSONArray; -end; - -procedure TRagna.UpdateById(AField: TField; AValue: Int64; ABody: TJSONObject); -begin - FQuery - .FindById(AField, AValue) - .OpenUp - .EditFromJson(ABody); -end; - -end. diff --git a/src/Ragna.Intf.pas b/src/Ragna.Intf.pas deleted file mode 100644 index 878f875..0000000 --- a/src/Ragna.Intf.pas +++ /dev/null @@ -1,43 +0,0 @@ -unit Ragna.Intf; - -interface - -uses - FireDAC.Comp.Client, System.JSON, Data.DB; - -type - - IRagna = interface - ['{0F1AD1E9-A82C-44BE-9208-685B9C3C77F9}'] - procedure Paginate(AOffSet, ALimit: integer); - procedure RadicalResearch(AValue: string; AFields: array of TField); - procedure Delete(AField: TField; AValue: Int64); - procedure FindById(AField: TField; AValue: Int64); - procedure UpdateById(AField: TField; AValue: Int64; ABody: TJSONObject); - procedure New(ABody: TJSONObject); - procedure OpenUp; - procedure StartCriteria; - procedure EndCriteria; - procedure ToJson(out AJSON: TJSONArray); overload; - procedure ToJson(out AJSON: TJSONObject); overload; - procedure EditFromJson(const AJSON: TJSONObject); - end; - - ICriteria = interface - ['{BC7603D3-DB7D-4A61-AA73-E1152A933E07}'] - procedure Where(AField: string); overload; - procedure Where(AField: TField); overload; - procedure Where(AValue: Boolean); overload; - procedure &Or(AField: string); overload; - procedure &Or(AField: TField); overload; - procedure &And(AField: string); overload; - procedure &And(AField: TField); overload; - procedure Like(AValue: string); - procedure &Equals(AValue: Int64); overload; - procedure &Equals(AValue: Boolean); overload; - procedure Order(AField: TField); - end; - -implementation - -end. diff --git a/src/Ragna.State.pas b/src/Ragna.State.pas deleted file mode 100644 index 31acbda..0000000 --- a/src/Ragna.State.pas +++ /dev/null @@ -1,118 +0,0 @@ -unit Ragna.State; - -interface - -uses - System.Generics.Collections; - -type - - TRagnaState = class - private - FSecret: string; - FStates: TThreadList>; - class var FInstance: TRagnaState; - public - property States: TThreadList < TPair < Pointer, string >> read FStates - write FStates; - procedure SetState(APointer: Pointer; ASQL: string); - function GetState(APointer: Pointer): string; - function RemoveState(APointer: Pointer): string; - class function GetInstance: TRagnaState; - class procedure Release; - constructor Create; - destructor Destroy; - end; - -implementation - -{ TRagnaState } - -constructor TRagnaState.Create; -begin - FStates := TThreadList < TPair < Pointer, string >>.Create; -end; - -destructor TRagnaState.Destroy; -begin - FStates.Free; -end; - -class function TRagnaState.GetInstance: TRagnaState; -begin - if not assigned(FInstance) then - FInstance := TRagnaState.Create; - Result := FInstance; -end; - -function TRagnaState.GetState(APointer: Pointer): string; -var - LState: TPair; - LStates: TList>; -begin - LStates := FStates.LockList; - try - for LState in LStates do - begin - if LState.Key = APointer then - begin - Result := LState.Value; - Break; - end; - end; - finally - FStates.UnlockList; - end; -end; - -class procedure TRagnaState.Release; -begin - FInstance.Free; -end; - -function TRagnaState.RemoveState(APointer: Pointer): string; -var - LState: TPair; - LStates: TList>; -begin - LStates := FStates.LockList; - try - for LState in LStates do - begin - if LState.Key = APointer then - begin - Result := LState.Value; - Break; - end; - end; - finally - FStates.UnlockList; - end; - - LStates.Remove(LState); -end; - -procedure TRagnaState.SetState(APointer: Pointer; ASQL: string); -var - LState: TPair; -begin -// TMonitor.Enter(FList); - try -// FList.Add(); - finally -// TMonitor.Exit(FList); - end; - - LState := TPair.Create(APointer, ASQL); - FStates.Add(LState); -end; - -initialization - -TRagnaState.GetInstance; - -finalization - -TRagnaState.Release; - -end. diff --git a/src/Ragna.pas b/src/Ragna.pas deleted file mode 100644 index a0ecd75..0000000 --- a/src/Ragna.pas +++ /dev/null @@ -1,367 +0,0 @@ -unit Ragna; - -interface - -uses - FireDAC.Comp.Client, System.JSON, Data.DB, Ragna.Impl; - -type - - TRagnaHelper = class helper for TFDQuery - public - function Paginate(AOffSet, ALimit: integer): TFDQuery; - function RadicalResearch(AValue: string; AFields: array of TField) - : TFDQuery; - function Delete(AField: TField; AValue: Int64): TFDQuery; - function FindById(AField: TField; AValue: Int64): TFDQuery; - function UpdateById(AField: TField; AValue: Int64; ABody: TJSONObject) - : TFDQuery; - function New(ABody: TJSONObject): TFDQuery; - function OpenUp: TFDQuery; - function StartCriteria: TFDQuery; - function EndCriteria: TFDQuery; - function ToJson(out AJSON: TJSONArray): TFDQuery; overload; - function ToJson(out AJSON: TJSONObject): TFDQuery; overload; - function EditFromJson(const AJSON: TJSONObject): TFDQuery; - function Where(AField: string): TFDQuery; overload; - function Where(AField: TField): TFDQuery; overload; - function Where(AValue: Boolean): TFDQuery; overload; - function &Or(AField: TField): TFDQuery; overload; - function &Or(AField: string): TFDQuery; overload; - function &And(AField: TField): TFDQuery; overload; - function &And(AField: string): TFDQuery; overload; - function Like(AValue: string): TFDQuery; - function &Equals(AValue: Int64): TFDQuery; overload; - function &Equals(AValue: Boolean): TFDQuery; overload; - function Order(AField: TField): TFDQuery; - end; - -implementation - -uses System.SysUtils; - -function TRagnaHelper.&Or(AField: TField): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.&Or(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.&And(AField: TField): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.&And(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.&And(AField: string): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.&And(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.&Or(AField: string): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.&Or(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Delete(AField: TField; AValue: Int64): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Delete(AField, AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.EndCriteria: TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.EndCriteria; - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Equals(AValue: Boolean): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Equals(AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Equals(AValue: Int64): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Equals(AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.FindById(AField: TField; AValue: Int64): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.FindById(AField, AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.EditFromJson(const AJSON: TJSONObject): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.EditFromJson(AJSON); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Like(AValue: string): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Like(AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.OpenUp: TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.OpenUp; - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Order(AField: TField): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Order(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Paginate(AOffSet, ALimit: integer): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Paginate(AOffSet, ALimit); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.New(ABody: TJSONObject): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.New(ABody); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.RadicalResearch(AValue: string; AFields: array of TField) - : TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.RadicalResearch(AValue, AFields); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.StartCriteria: TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.StartCriteria; - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.ToJson(out AJSON: TJSONObject): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.ToJson(AJSON); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.ToJson(out AJSON: TJSONArray): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.ToJson(AJSON); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.UpdateById(AField: TField; AValue: Int64; - ABody: TJSONObject): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.UpdateById(AField, AValue, ABody); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Where(AField: string): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Where(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Where(AValue: Boolean): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Where(AValue); - finally - LRagna.Free; - end; - - Result := Self; -end; - -function TRagnaHelper.Where(AField: TField): TFDQuery; -var - LRagna: TRagna; -begin - LRagna := TRagna.Create(Self); - try - LRagna.Criteria.Where(AField); - finally - LRagna.Free; - end; - - Result := Self; -end; - -end. diff --git a/src/core/Ragna.Criteria.Impl.pas b/src/core/Ragna.Criteria.Impl.pas new file mode 100644 index 0000000..f98902b --- /dev/null +++ b/src/core/Ragna.Criteria.Impl.pas @@ -0,0 +1,145 @@ +unit Ragna.Criteria.Impl; +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} +interface +uses {$IFDEF UNIDAC}Uni{$ELSE}FireDAC.Comp.Client, FireDAC.Stan.Param{$ENDIF}, + StrUtils, Data.DB, System.Hash, Ragna.Criteria.Intf, Ragna.Types; +type + TDefaultCriteria = class(TInterfacedObject, ICriteria) + private + FQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + procedure Where(const AField: string); + procedure &Or(const AField: string); + procedure &And(const AField: string); + procedure Like(const AValue: string); + procedure &Equals(const AValue: Int64); reintroduce; overload; + procedure &Equals(const AValue: Boolean); reintroduce; overload; + procedure &Equals(const AValue: string); reintroduce; overload; + procedure &Equals(const AValue: TGuid); reintroduce; overload; + procedure Order(const AField: string); + public + constructor Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); + end; + TManagerCriteria = class + private + FCriteria: ICriteria; + function GetDrive(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}): string; + function GetInstanceCriteria(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}): ICriteria; + public + constructor Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); + property Criteria: ICriteria read FCriteria write FCriteria; + end; +implementation +uses FireDAC.Stan.Intf, SysUtils; +procedure TDefaultCriteria.&And(const AField: string); +const + PHRASE = '%s %s'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.AND.ToString, AField])); +end; +procedure TDefaultCriteria.&Or(const AField: string); +const + PHRASE = ' %s %s'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.OR.ToString, AField])); +end; +constructor TDefaultCriteria.Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); +begin + FQuery := AQuery; +end; +procedure TDefaultCriteria.Equals(const AValue: Boolean); +const + PHRASE = '%s %s'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.EQUALS.ToString, BoolToStr(AValue, True)])); +end; +procedure TDefaultCriteria.Equals(const AValue: Int64); +const + PHRASE = '%s %d'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.EQUALS.ToString, AValue])); +end; +procedure TDefaultCriteria.Equals(const AValue: string); +const + PHRASE = '%s ''%s'''; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.EQUALS.ToString, AValue])); +end; +procedure TDefaultCriteria.Like(const AValue: string); +const + PHRASE = ' %s %s'; +var + LKeyParam: string; + LParam: {$IFDEF UNIDAC}TUniParam{$ELSE}TFDParam{$ENDIF}; +begin + LKeyParam := THashMD5.Create.HashAsString; + FQuery.SQL.Text := FQuery.SQL.Text + Format(PHRASE, [TOperatorType.LIKE.ToString, ':' + LKeyParam]); + LParam := FQuery.ParamByName(LKeyParam); + LParam.DataType := ftString; + if Pos('%', AValue) <= 0 then + LParam.Value := AValue + '%' + else + LParam.Value := AValue; +end; +procedure TDefaultCriteria.Where(const AField: string); +const + PHRASE = '%s %s'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.WHERE.ToString, AField])); +end; +procedure TDefaultCriteria.Order(const AField: string); +const + PHRASE = '%s %s'; +begin + FQuery.SQL.Add(Format(PHRASE, [TOperatorType.ORDER.ToString, AField])); +end; +constructor TManagerCriteria.Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); +begin + FCriteria := GetInstanceCriteria(AQuery); +end; +function TManagerCriteria.GetDrive(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}): string; +{$IFDEF UNIDAC} +begin + Result := AQuery.Connection.ProviderName; +end; +{$ELSE} +var + LDef: IFDStanConnectionDef; +begin + Result := AQuery.Connection.DriverName; + if Result.IsEmpty and not AQuery.Connection.ConnectionDefName.IsEmpty then + begin + LDef := FDManager.ConnectionDefs.FindConnectionDef(AQuery.Connection.ConnectionDefName); + if LDef = nil then + raise Exception.Create('ConnectionDefs "' + AQuery.Connection.ConnectionDefName + '" not found'); + Result := LDef.Params.DriverID; + end; +end; +{$ENDIF} +function TManagerCriteria.GetInstanceCriteria(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}): ICriteria; +begin + case AnsiIndexStr(GetDrive(AQuery), ['PG']) of + 0: + Result := TDefaultCriteria.Create(AQuery); + else + Result := TDefaultCriteria.Create(AQuery); + end; +end; +procedure TDefaultCriteria.Equals(const AValue: TGuid); +const + PHRASE = ' %s %s'; +var + LKeyParam: string; + LParam: {$IFDEF UNIDAC}TUniParam{$ELSE}TFDParam{$ENDIF}; +begin + LKeyParam := THashMD5.Create.HashAsString; + + FQuery.SQL.Text := FQuery.SQL.Text + Format(PHRASE, [TOperatorType.EQUALS.ToString, ':' + LKeyParam]); + + LParam := FQuery.ParamByName(LKeyParam); + LParam.DataType := ftGuid; + LParam.AsGUID := AValue; +end; + +end. diff --git a/src/core/Ragna.Impl.pas b/src/core/Ragna.Impl.pas new file mode 100644 index 0000000..39997f2 --- /dev/null +++ b/src/core/Ragna.Impl.pas @@ -0,0 +1,309 @@ +unit Ragna.Impl; +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} +interface +uses {$IFDEF UNIDAC}Uni, SqlClassesUni{$ELSE}FireDAC.Comp.Client{$ENDIF}, Ragna.Intf, Ragna.Criteria.Intf, System.JSON, Data.DB, Ragna.Criteria.Impl; +type + TRagna = class(TInterfacedObject, IRagna) + private + FQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + FManagerCriteria: TManagerCriteria; + FCriteria: ICriteria; + procedure SaveState; + private + function HasField(const AFields: array of TField): Boolean; + function ToJSONObject: TJSONObject; + function ToJSONArray: TJSONArray; + procedure RaiseNotFound; + procedure Paginate(const AOffSet, ALimit: Integer); {$IFDEF UNIDAC} deprecated 'Not implemented for UniDAC';{$ENDIF} + procedure RadicalResearch(const AValue: string; const AFields: array of TField); + procedure Remove(const AField: TField; const AValue: Int64); overload; + procedure Remove(const AField: TField; const AValue: string; const AGuid: Boolean = False); overload; + procedure Remove(const AField: TField; const AValue: TGuid); overload; + procedure FindById(const AField: TField; const AValue: TGuid); overload; + procedure FindById(const AField: TField; const AValue: Int64); overload; + procedure FindById(const AField: TField; const AValue: string; const AGuid: Boolean = False); overload; + procedure UpdateById(const AField: TField; const AValue: Int64; const ABody: TJSONObject); overload; + procedure UpdateById(const AField: TField; const AValue: string; const ABody: TJSONObject; const AGuid: Boolean = False); overload; + procedure UpdateById(const AField: TField; const AValue: TGuid; const ABody: TJSONObject); overload; + procedure OpenUp; + procedure OpenEmpty; + procedure Reset; + procedure EditFromJson(const AJSON: TJSONObject); overload; + procedure EditFromJson(const AJSON: TJSONArray); overload; + procedure EditFromJson(const AJSON: string); overload; + procedure New(const ABody: TJSONObject); overload; + procedure New(const ABody: TJSONArray); overload; + procedure New(const ABody: string); overload; + function GetTableName(const CommandText: string): string; + function RemoverEspacosParenteses(const Texto: string): string; + public + constructor Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); + property Query: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF} read FQuery write FQuery; + property Criteria: ICriteria read FCriteria write FCriteria; + destructor Destroy; override; + end; +implementation +uses Ragna.State, System.SysUtils, Ragna, DataSet.Serialize; +constructor TRagna.Create(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); +begin + FQuery := AQuery; + SaveState; + FManagerCriteria := TManagerCriteria.Create(FQuery); + FCriteria := FManagerCriteria.Criteria; +end; +procedure TRagna.Remove(const AField: TField; const AValue: Int64); +const + DELETE_SQL = 'DELETE FROM %s WHERE %s = :ID'; + DELETED: array [0 .. 1] of Boolean = (False, True); +var + LDeleted: Integer; + LSql: string; +begin + LSql := Format(DELETE_SQL, [GetTableName(FQuery.sql.Text), AField.FieldName]); + LDeleted := FQuery.Connection.ExecSQL(LSql, [AValue]); + if not DELETED[LDeleted] then + RaiseNotFound; +end; +destructor TRagna.Destroy; +begin + FManagerCriteria.Free; +end; +procedure TRagna.EditFromJson(const AJSON: string); +begin + FQuery.MergeFromJSONObject(AJSON); +end; +procedure TRagna.FindById(const AField: TField; const AValue: TGuid); +var + LField: string; +begin + LField := GetTableName(FQuery.SQL.Text) + '.' + AField.Origin; + FQuery.Reset.Where(LField).Equals(AValue); +end; + +procedure TRagna.FindById(const AField: TField; const AValue: string; + const AGuid: Boolean); +var + LField: string; +begin + if AGuid then + FindById(AField, StringToGuid(AValue)) + else + begin + LField := GetTableName(FQuery.SQL.Text) + '.' + AField.Origin; + FQuery.Reset.Where(LField).Equals(AValue); + end; +end; + +procedure TRagna.SaveState; +var + LSql: string; +begin + if not TRagnaState.GetInstance.GetState(FQuery, LSql) then + TRagnaState.GetInstance.SetState(FQuery, FQuery.SQL.Text); +end; +procedure TRagna.EditFromJson(const AJSON: TJSONArray); +begin + FQuery.LoadFromJSON(AJSON, False); +end; +procedure TRagna.FindById(const AField: TField; const AValue: Int64); +var + LField: string; +begin + LField := GetTableName(FQuery.SQL.Text) + '.' + AField.Origin; + FQuery.Reset.Where(LField).Equals(AValue); +end; +procedure TRagna.EditFromJson(const AJSON: TJSONObject); +begin + FQuery.MergeFromJSONObject(AJSON, False); +end; +function TRagna.HasField(const AFields: array of TField): Boolean; +begin + Result := Length(AFields) > 0; +end; +procedure TRagna.New(const ABody: string); +begin + OpenEmpty; + FQuery.LoadFromJSON(ABody); +end; +procedure TRagna.New(const ABody: TJSONArray); +begin + OpenEmpty; + FQuery.LoadFromJSON(ABody); +end; +procedure TRagna.OpenUp; +begin + FQuery.Open; +end; +procedure TRagna.OpenEmpty; +begin + FQuery.Where('1').Equals('2').OpenUp; +end; +procedure TRagna.Paginate(const AOffSet, ALimit: Integer); +begin + {$IFDEF UNIDAC} + raise Exception.Create('Not implemented for UniDAC'); + {$ELSE} + if AOffSet > 0 then + FQuery.FetchOptions.RecsSkip := AOffSet; + if ALimit > 0 then + FQuery.FetchOptions.RecsMax := ALimit; + {$ENDIF} +end; +procedure TRagna.New(const ABody: TJSONObject); +begin + OpenEmpty; + FQuery.LoadFromJSON(ABody); +end; +procedure TRagna.RadicalResearch(const AValue: string; const AFields: array of TField); +var + LSearch: string; + LCount: Integer; +begin + if HasField(AFields) and not AValue.IsEmpty then + begin + LSearch := '%' + AValue + '%'; + FQuery.Where(AFields[0]).Like(LSearch); + if ((Length(AFields) - 1) >= 2) then + begin + for LCount := 1 to Length(AFields) - 1 do + FQuery.&Or(AFields[LCount]).Like(LSearch); + end; + end; +end; +procedure TRagna.RaiseNotFound; +begin + raise Exception.Create('Resource not found!'); +end; +procedure TRagna.Reset; +var + LSql: string; +begin + TRagnaState.GetInstance.GetState(FQuery, LSql); + FQuery.SQL.Text := LSql; +end; +function TRagna.ToJSONArray: TJSONArray; +begin + Result := (FQuery as TDataSet).ToJSONArray; +end; +function TRagna.ToJSONObject: TJSONObject; +begin + if FQuery.IsEmpty then + RaiseNotFound; + Result := (FQuery as TDataSet).ToJSONObject; +end; +procedure TRagna.UpdateById(const AField: TField; const AValue: TGuid; + const ABody: TJSONObject); +begin + FQuery.FindById(AField, AValue).OpenUp.MergeFromJSONObject(ABody, False); +end; + +procedure TRagna.UpdateById(const AField: TField; const AValue: string; + const ABody: TJSONObject; const AGuid: Boolean); +begin + FQuery.FindById(AField, AValue, AGuid).OpenUp.MergeFromJSONObject(ABody, False); +end; + +procedure TRagna.UpdateById(const AField: TField; const AValue: Int64; const ABody: TJSONObject); +begin + FQuery.FindById(AField, AValue).OpenUp.MergeFromJSONObject(ABody, False); +end; + +function TRagna.GetTableName(const CommandText: string): string; +var + LCopy: Boolean; + I, ParentesesAbertos: Integer; + Tabela, LFrom: string; +begin + LCopy := False; + Tabela := EmptyStr; + Result := RemoverEspacosParenteses(CommandText.Replace(' ', EmptyStr)); + ParentesesAbertos := 0; + for I := 1 to Result.Length do + begin + if Result[I] = '(' then + begin + if Copy(LowerCase(Result), I + 1, 6) = 'select' then + begin + Inc(ParentesesAbertos); + Continue; + end; + if ParentesesAbertos > 0 then + Inc(ParentesesAbertos); + end + else if (Result[I] = ')') and (ParentesesAbertos > 0) then + begin + Dec(ParentesesAbertos); + Continue; + end; + if (ParentesesAbertos = 0) then + begin + LFrom := Copy(Result, I-5, 5); + if LFrom.ToLower.Equals('from ') then + LCopy := True; + if LCopy then + begin + if Ord(Result[I]) = 10 then + Break; + Tabela := Tabela + Result[I]; + end; + end; + end; + Result := Tabela.Trim; +end; +procedure TRagna.Remove(const AField: TField; const AValue: string; + const AGuid: Boolean); +const + DELETE_SQL = 'DELETE FROM %s WHERE %s = :ID'; + DELETED: array [0 .. 1] of Boolean = (False, True); +var + LDeleted: Integer; + LSql: string; +begin + if AGuid then + Remove(AField, StringToGUID(AValue)) + else + begin + LDeleted := FQuery.Connection.ExecSQL(LSql, [AValue]); + if not DELETED[LDeleted] then + RaiseNotFound; + end; +end; + +procedure TRagna.Remove(const AField: TField; const AValue: TGuid); +const + DELETE_SQL = 'DELETE FROM %s WHERE %s = :ID'; + DELETED: array [0 .. 1] of Boolean = (False, True); +var + LDeleted: Integer; + LSql: string; +begin + LSql := Format(DELETE_SQL, [GetTableName(FQuery.sql.Text), AField.FieldName]); + + FQuery.SQL.Text := LSQL; + FQuery.ParamByName('ID').AsGUID := AValue; + LDeleted := FQuery.ExecSQL(true); + + if not DELETED[LDeleted] then + RaiseNotFound; +end; + +function TRagna.RemoverEspacosParenteses(const Texto: string): string; +var + I: Integer; +begin + Result := EmptyStr; + for I := 1 to Texto.Length do + begin + if not Result.Trim.IsEmpty then + begin + if (Result[Result.Length] = '(') and (Texto[I] = ' ') then + Continue; + if (Texto[I] = ' ') and (Texto[I + 1] = ')') then + Continue; + end; + Result := Result + Texto[I]; + end; +end; +end. diff --git a/src/helpers/Ragna.pas b/src/helpers/Ragna.pas new file mode 100644 index 0000000..8f63e2e --- /dev/null +++ b/src/helpers/Ragna.pas @@ -0,0 +1,361 @@ +unit Ragna; +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} +interface +uses {$IFDEF UNIDAC}Uni{$ELSE}FireDAC.Comp.Client{$ENDIF}, System.JSON, Data.DB, Ragna.Impl, Ragna.Criteria.Impl; +type + TRagnaHelper = class helper for {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF} + public + function Paginate(const AOffSet, ALimit: Integer): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + function RadicalResearch(const AValue: string; const AFields: array of TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + function Remove(const AField: TField; const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Remove(const AField: TField; const AValue: TGuid): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Remove(const AField: TField; const AValue: string; const AGuid: Boolean = False): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function FindById(const AField: TField; const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function FindById(const AField: TField; const AValue: TGuid): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function FindById(const AField: TField; const AValue: string; const AGuid: Boolean = False): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function UpdateById(const AField: TField; const AValue: Int64; const ABody: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function UpdateById(const AField: TField; const AValue: TGuid; const ABody: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function UpdateById(const AField: TField; const AValue: string; const ABody: TJSONObject; const AGuid: Boolean = False): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Reset: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + function OpenUp: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + function OpenEmpty: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; + function ToJSONObject: TJSONObject; + function ToJSONArray: TJSONArray; + function New(const ABody: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function New(const ABody: TJSONArray): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function New(const ABody: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function EditFromJson(const AJSON: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function EditFromJson(const AJSON: TJSONArray): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function EditFromJson(const AJSON: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Where(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Where(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Where(const AValue: Boolean): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Or(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Or(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &And(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &And(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Like(const AValue: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Like(const AValue: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Equals(const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Equals(const AValue: Boolean): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Equals(const AValue: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function &Equals(const AValue: TGuid): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Order(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + function Order(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; overload; + end; +implementation +uses System.SysUtils, Ragna.Intf; +function TRagnaHelper.&Or(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := &Or(AField.Origin); +end; +function TRagnaHelper.&And(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := &And(AField.Origin); +end; +function TRagnaHelper.&And(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.&And(AField); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.&Or(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.&Or(AField); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.Order(const AField: string): TFDQuery; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.Order(AField); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.Remove(const AField: TField; const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Remove(AField, AValue); + Result := Self; +end; +function TRagnaHelper.EditFromJson(const AJSON: TJSONArray): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.EditFromJson(AJSON); + Result := Self; +end; +function TRagnaHelper.EditFromJson(const AJSON: string): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.EditFromJson(AJSON); + Result := Self; +end; +function TRagnaHelper.Equals(const AValue: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Criteria.Equals(AValue); + Result := Self; +end; +function TRagnaHelper.Equals(const AValue: Boolean): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.Equals(AValue); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.Equals(const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.Equals(AValue); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.FindById(const AField: TField; const AValue: Int64): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.FindById(AField, AValue); + Result := Self; +end; +function TRagnaHelper.Like(const AValue: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := Like(AValue.AsString); +end; +function TRagnaHelper.EditFromJson(const AJSON: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.EditFromJson(AJSON); + Result := Self; +end; +function TRagnaHelper.Like(const AValue: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.Like(AValue); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.New(const ABody: TJSONArray): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.New(ABody); + Result := Self; +end; +function TRagnaHelper.OpenEmpty: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.OpenEmpty; + Result := Self; +end; +function TRagnaHelper.OpenUp: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.OpenUp; + Result := Self; +end; +function TRagnaHelper.Order(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := Order(AField.Origin); +end; +function TRagnaHelper.Paginate(const AOffSet, ALimit: Integer): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Paginate(AOffSet, ALimit); + Result := Self; +end; +function TRagnaHelper.New(const ABody: TJSONObject): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.New(ABody); + Result := Self; +end; +function TRagnaHelper.RadicalResearch(const AValue: string; const AFields: array of TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.RadicalResearch(AValue, AFields); + Result := Self; +end; +function TRagnaHelper.Remove(const AField: TField; const AValue: string; + const AGuid: Boolean): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Remove(AField, AValue, AGuid); + Result := Self; +end; + +function TRagnaHelper.Remove(const AField: TField; + const AValue: TGuid): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Remove(AField, AValue); + Result := Self; +end; + +function TRagnaHelper.Reset: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Reset; + Result := Self; +end; +function TRagnaHelper.ToJSONArray: TJSONArray; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + Result := LRagna.ToJSONArray; +end; +function TRagnaHelper.ToJSONObject: TJSONObject; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + Result := LRagna.ToJSONObject; +end; +function TRagnaHelper.UpdateById(const AField: TField; const AValue: TGuid; + const ABody: TJSONObject): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.UpdateById(AField, AValue, ABody); + Result := Self; +end; + +function TRagnaHelper.UpdateById(const AField: TField; const AValue: string; + const ABody: TJSONObject; const AGuid: Boolean): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.UpdateById(AField, AValue, ABody, AGuid); + Result := Self; +end; + +function TRagnaHelper.UpdateById(const AField: TField; const AValue: Int64; const ABody: TJSONObject): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.UpdateById(AField, AValue, ABody); + Result := Self; +end; +function TRagnaHelper.Where(const AField: string): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + try + LRagna.Criteria.Where(AField); + finally + LRagna.Free; + end; + Result := Self; +end; +function TRagnaHelper.Where(const AValue: Boolean): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := Where(BoolToStr(AValue, True)); +end; +function TRagnaHelper.Where(const AField: TField): {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; +begin + Result := Where(AField.Origin); +end; +function TRagnaHelper.New(const ABody: string): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.New(ABody); + Result := Self; +end; +function TRagnaHelper.Equals(const AValue: TGuid): TFDQuery; +var + LRagna: TRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.Criteria.Equals(AValue); + Result := Self; +end; + +function TRagnaHelper.FindById(const AField: TField; + const AValue: TGuid): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.FindById(AField, AValue); + Result := Self; +end; + +function TRagnaHelper.FindById(const AField: TField; const AValue: string; + const AGuid: Boolean): TFDQuery; +var + LRagna: IRagna; +begin + LRagna := TRagna.Create(Self); + LRagna.FindById(AField, AValue, AGuid); + Result := Self; +end; + +end. diff --git a/src/interfaces/Ragna.Criteria.Intf.pas b/src/interfaces/Ragna.Criteria.Intf.pas new file mode 100644 index 0000000..92dfe0e --- /dev/null +++ b/src/interfaces/Ragna.Criteria.Intf.pas @@ -0,0 +1,25 @@ +unit Ragna.Criteria.Intf; + +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} + +interface + +type + ICriteria = interface + ['{BC7603D3-DB7D-4A61-AA73-E1152A933E07}'] + procedure Where(const AField: string); + procedure &Or(const AField: string); + procedure &And(const AField: string); + procedure Like(const AValue: string); + procedure &Equals(const AValue: Int64); overload; + procedure &Equals(const AValue: Boolean); overload; + procedure &Equals(const AValue: string); overload; + procedure &Equals(const AValue: TGuid); overload; + procedure Order(const AField: string); + end; + +implementation + +end. diff --git a/src/interfaces/Ragna.Intf.pas b/src/interfaces/Ragna.Intf.pas new file mode 100644 index 0000000..68857ba --- /dev/null +++ b/src/interfaces/Ragna.Intf.pas @@ -0,0 +1,40 @@ +unit Ragna.Intf; + +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} + +interface + +uses FireDAC.Comp.Client, System.JSON, Data.DB; + +type + IRagna = interface + ['{0F1AD1E9-A82C-44BE-9208-685B9C3C77F9}'] + procedure Paginate(const AOffSet, ALimit: Integer); + procedure RadicalResearch(const AValue: string; const AFields: array of TField); + procedure Remove(const AField: TField; const AValue: Int64); overload; + procedure Remove(const AField: TField; const AValue: string; const AGuid: Boolean = False); overload; + procedure Remove(const AField: TField; const AValue: TGuid); overload; + procedure FindById(const AField: TField; const AValue: TGuid); overload; + procedure FindById(const AField: TField; const AValue: Int64); overload; + procedure FindById(const AField: TField; const AValue: string; const AGuid: Boolean = False); overload; + procedure UpdateById(const AField: TField; const AValue: Int64; const ABody: TJSONObject); overload; + procedure UpdateById(const AField: TField; const AValue: string; const ABody: TJSONObject; const AGuid: Boolean = False); overload; + procedure UpdateById(const AField: TField; const AValue: TGuid; const ABody: TJSONObject); overload; + procedure OpenUp; + procedure OpenEmpty; + procedure Reset; + procedure EditFromJson(const AJSON: TJSONObject); overload; + procedure EditFromJson(const AJSON: TJSONArray); overload; + procedure EditFromJson(const AJSON: string); overload; + procedure New(const ABody: TJSONObject); overload; + procedure New(const ABody: TJSONArray); overload; + procedure New(const ABody: string); overload; + function ToJSONArray: TJSONArray; + function ToJSONObject: TJSONObject; + end; + +implementation + +end. diff --git a/src/state/Ragna.State.pas b/src/state/Ragna.State.pas new file mode 100644 index 0000000..9ca9fa9 --- /dev/null +++ b/src/state/Ragna.State.pas @@ -0,0 +1,98 @@ +unit Ragna.State; + +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} + +interface + +uses System.Generics.Collections, {$IFDEF UNIDAC}Uni{$ELSE}FireDac.Comp.Client{$ENDIF}, System.Rtti; + +type + TListQueryAndSql = TDictionary<{$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}, string>; + + TRagnaState = class + private + FStates: TListQueryAndSql; + FVmi: TVirtualMethodInterceptor; + class var FInstance: TRagnaState; + procedure OnBeforVMI(Instance: TObject; Method: TRttiMethod; const Args: TArray; out DoInvoke: Boolean; out Result: TValue); + public + destructor Destroy; override; + property States: TListQueryAndSql read FStates write FStates; + procedure SetState(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; const ASQL: string); + function GetState(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; out ASQL: string): Boolean; + class function GetInstance: TRagnaState; + class procedure Release; + constructor Create; + end; + +implementation + +constructor TRagnaState.Create; +begin + FVmi := TVirtualMethodInterceptor.Create({$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); + FVmi.OnBefore := OnBeforVMI; + FStates := TListQueryAndSql.Create; +end; + +destructor TRagnaState.Destroy; +begin + FStates.Free; + FVmi.Free; +end; + +class function TRagnaState.GetInstance: TRagnaState; +begin + if not assigned(FInstance) then + FInstance := TRagnaState.Create; + Result := FInstance; +end; + +function TRagnaState.GetState(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; out ASQL: string): Boolean; +begin + TMonitor.Enter(FStates); + try + Result := FStates.TryGetValue(AQuery, ASQL); + finally + TMonitor.Exit(FStates); + end; +end; + +procedure TRagnaState.OnBeforVMI(Instance: TObject; Method: TRttiMethod; const Args: TArray; out DoInvoke: Boolean; + out Result: TValue); +begin + if Method.Name <> 'BeforeDestruction' then + Exit; + TMonitor.Enter(FStates); + try + FStates.Remove(Instance as {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}); + finally + TMonitor.Exit(FStates); + end; +end; + +class procedure TRagnaState.Release; +begin + FInstance.Free; +end; + +procedure TRagnaState.SetState(const AQuery: {$IFDEF UNIDAC}TUniQuery{$ELSE}TFDQuery{$ENDIF}; const ASQL: string); +begin + TMonitor.Enter(FStates); + try + if FVmi.ProxyClass <> AQuery.ClassType then + FVmi.Proxify(AQuery); + FStates.AddOrSetValue(AQuery, ASQL); + finally + TMonitor.Exit(FStates); + end; +end; + +initialization + TRagnaState.GetInstance; + +finalization + TRagnaState.Release; + +end. diff --git a/src/types/Ragna.Types.pas b/src/types/Ragna.Types.pas new file mode 100644 index 0000000..6277405 --- /dev/null +++ b/src/types/Ragna.Types.pas @@ -0,0 +1,39 @@ +unit Ragna.Types; + +{$IF DEFINED(FPC)} + {$MODE DELPHI}{$H+} +{$ENDIF} + +interface + +type +{$SCOPEDENUMS ON} + TOperatorType = (WHERE, &OR, LIKE, EQUALS, ORDER, &AND); +{$SCOPEDENUMS OFF} + + TOperatorTypeHelper = record helper for TOperatorType + public + function ToString: string; + end; + +implementation + +function TOperatorTypeHelper.ToString: string; +begin + case Self of + TOperatorType.WHERE: + Result := 'WHERE'; + TOperatorType.OR: + Result := 'OR'; + TOperatorType.LIKE: + Result := 'LIKE'; + TOperatorType.EQUALS: + Result := '='; + TOperatorType.ORDER: + Result := 'ORDER BY'; + TOperatorType.AND: + Result := 'AND'; + end; +end; + +end.