![]() |
EasyLINQ, eine generische Liste die einfache SQL Befehle ausführt
Liste der Anhänge anzeigen (Anzahl: 5)
Hallo liebe DP-ler,
oft braucht man Objektlisten, die gefiltert, sortiert oder gruppiert werden müssen. Unter Delphi Prism bzw. .net gibt es LINQ, das man in solchen Fällen sicher zu schätzen weiss. Leider gibt es unter Delphi selbst nichts dergleichen. Darum habe ich einmal etwas in diese Richtung erstellt. Aus Zeitgründen sicher noch nicht perfekt, aber es arbeitet soweit zufriedenstellend... Welche SQL-Befehle werden unterstützt?
Zur Funktionsweise: Die Liste kann Klassen oder Records verwalten. Records haben derzeit die Limitierung, dass in die Werte nicht geschrieben werden kann. Somit funktionieren CALC und UPDATE nicht. Eine Exception wird ausgelöst, wenn versucht wird einen der Befehle in Verbindung mit Records zu nutzen. Enumeration wird unterstützt, daher auch "for in" möglich. Handhabung also wie TList<T>. Durch den Befehl "Execute()" wird das Kommando abgesetzt und eine neues Objekt als Lookup-Liste zurückgegeben. Löschen von Objekten ist in einer Lookup-Liste nicht möglich. Zur Berechnung von Werten habe ich eine Calculator Klasse eingebunden. Mit ihr lassen sich einfache Rechenoperationen durchführen und deren Ergebnisse wieder in Properties von Klassen zurückschreiben. Unterstützt werden die Operatoren - + / * ^ ( ) sin cos tan sqr log cot sec csc Was gilt es zu beachten?
Neues Update:
Update, Version 1.3, 30.1.2013
Update, Version 1.4, 15.8.2014 Update, Version 1.41, 4.9.2014 Im Laufe der Zeit wird sich sicher noch die eine oder andere Funktion ergeben. Mit dem Parser bin ich noch nicht so ganz glücklich, hier lässt sich auf jeden Fall noch einiges optimieren. Derzeit müssen Ausdrücke in Klammern gesetzt werden, das vereinfacht das Parsen. Beispiel:
Delphi-Quellcode:
ClassLinq := TLinq<TMyClass>.Create;
{...} TempLinq := ClassLinq.Execute( 'ORDER BY LastName, FirstName' ); for item in TempLinq do Memo1.Lines.Add( item.ToString ); TempLinq.Free; {...} ClassLinq.Free Einige SQL-Beispiele aus der beiliegenden Demo:
Delphi-Quellcode:
SELECT WHERE (City="Vienna")
SELECT ORDER BY City,Value SELECT ORDER BY City,Value DESC SELECT TOP(3) WHERE (UPPER(Lastname) like "%A%") ORDER BY MySubText.Text SELECT CALC(value=(value*32+4)/2) ORDER BY value SELECT TOP(3) WHERE (LOWER(Firstname)="kurt") OR (LOWER(Firstname)="edmund") SELECT GROUP BY City ORDER BY LastName SELECT WHERE (MySubText.Text="Sub3") OR (FirstName="Kurt") UPDATE SET (Firstname="Max", Lastname="Mustermann") WHERE (City="Linz") OR (MySubText.Text="Sub4") UPDATE SET (Value=CALC(23*2-4)) WHERE (City="Vienna") Ideen und Wünsche für Erweiterungen und Verbesserungen sind gerne willkommen... liebe Grüße, Daniela |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Klingt interessant, werde es mir später mal anschauen. Ich arbeite auch seit einiger Zeit an einer Linq ähnlichen Sache für Delphi (unter Zuhilfenahme der
![]() |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
jössas, so viel Zeit habe ich gar nicht. Ich hab das in drei Stunden zusammengebastelt. Im Moment habe ich leider wenig Zeit und solche Sortier- und Gruppiergeschichten halten mich immer unnötig auf. Daher diese kleine (wirklich kleine) Klasse :wink:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Was ist denn mit
![]() |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Ahso. Ja denn.
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Die Komponente ist eine gute Idee. Vielleicht gerade weil sie klein und überschaubar sit.
Grüße in die Runde |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Die Idee ist super!
Werde ich mir demnächst mal gern mit anschauen. PS: Eine native Linq-Lösung hätte ich mir für XE2 erhofft. (Die tatsächlichen Neuerungen interessieren mich persönlich erst mal weniger.) |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Das Problem ist oft, dass die Bibliotheken wahnsinnig überladen sind und teilweise eine hohe Einarbeitungszeit benötigen. Auch sind manche Lösungen recht kompliziert. Dann einen Fehler zu suchen dauert wiederum. Deshalb habe ich es bewusst aufs wesentliche reduziert.
Eine Funktion, die einfache Standard-SQL Befehle versteht, die Objekte danach ausrichtet und als Liste wieder zurückgibt. Man muss sich also nicht wieder in etwas einarbeiten. Es soll auch keinesfalls ein Ersatz für eine Datenbank sein. Hätte mir auch Linq gewünscht. Vielleicht mit XE3 oder XEⁿ :wink: |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
Und außerdem kranken die Generics aktuell immernoch an fehlerhafter type inference, wie ich heute wieder feststellen musste, die aber grundlegend für Features wie Linq notwendig ist. Barry schrieb schon an einigen Stellen, welche Probleme sie mit Lambdas aktuell haben, z.B. ![]() |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
Aber es stimmt: Für vollständige Type Inference braucht man einen Multipass Compiler, und Delphi ist historisch nunmal ein Single-Pass Compiler (was nicht heisst, dass der Compiler zwangsläufig alles mehrfach durchgehen muss, aber an manchen Stellen ist das eben nötig). |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Neues Update...
- Parser überarbeitet - Update Befehl hinzugefügt - Unterklassen werden unterstützt |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Mein Delphi 2010 stoplert über 2 Sachen:
In Calculator.Calulate benutzt du eine (scheinend globale?) Variable namens FormatSettings. Die gibt es bei mir nicht. Ich habe es so gelöst.
Delphi-Quellcode:
Der Call füür getlocale ist sicherlich weniger teuer, als sowas statisch für die Laufzeit der App zu cachen. (Da du ja dann keine Änderungen der Settings bemerken würdest)
FormatSettings : TFormatSettings;
begin fValid := True; if Length( s ) <3 then begin fValid := False; Exit( 0 ); end; SysUtils.GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FormatSettings); Dann benutzt du an 2 Stellen einen Safecast ("as") auf TObject, den mag mein Delphi auch nicht. Ich musst hier einen Hard-Cast machen:
Delphi-Quellcode:
Da du in beiden Fällen vorher die RTTI fragst, ob T eine Klasse ist, musst du hier auch nicht befürchten, dass du den Kater auf TEichhörnchen wurschtelst... :-)
//TLinQ<T>.Remove
TObject(fItems[index]).Free; //TLinQ<T>.Clear; for item in fItems do TObject(item).Free; Rein vom API-Design her, finde ich es ein wenig zu einvernehmend die Unit LinQ und die Klasse TLinq zu nennen. Solche doch sehr offensichtlichen Namen sollten dem Delphi-Team vorbehalten bleiben. Falls Delphi irgendwann sowas kriegt, könnten Unit- oder Type-Name mit dem kollidieren, was Borlemb aus dem Hut zaubert. Oder es kollidiert mit den sicherlich vorhandenen anderen LinQ-Workarounds für Delphi. Oh, und "SELECT" als Prefix ist anscheinend gar nicht nötig. Vllt einfach aus den Beispielen rausnehmen. Wirkt komisch, wenn man keine Property-liste angeben kann. Ansonsten ist das sicherlich eine nette Bereicherung für so manchen. :-) |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Wie schon geschrieben habe ich es noch nicht auf Delphi 2010 probiert. Derzeit verwende ich die Unit in einem XE Projekt. Aber ich stürze mich gleich nachher darauf :wink:
FormatSettings gibt es erst ab Delphi XE. Beinhaltet von da an den DecimalSeparator. Am Namen wird es nicht liegen, kann ich gerne ändern. Ich bezweifle jedoch dass Linq in absehbarer Zukunft erscheinen wird. Es wurde 2005 schon mal angekündigt. Was hat sich getan? Nix :| Nichtmal auf Roadmaps konnte ich das bisher erblicken. Solange Lambda, Extension Methods und Type Inference per Default nicht in irgendeiner Art implementiert sind, steht auch die grundlegende Technik dahinter nicht zur Verfügung. Bei XE2 muss ich erst schauen was sich in diesem Bereich getan hat. Großes Problem ist auch, dass es bei Generics in Delphi 2010 sehr viele Fehler gab. XE hat mir hier auch schon einige Interne Fehler geworfen. XE2 ist da schon um einiges besser. Und die Rtti funktioniert mit Records scheinbar immer noch nicht. Tante Edit sagt: Achja, Select ist Optional, kann man um der Syntax-Willen schreiben... |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
Letzteres wäre schon ganz schön Kac*e und sollte den Borlembern um die Ohren geworfen werden. Aber wenn ich FormatSettings als lokale Variable nehme und in Calculate mit der Änderung oben besetze fluppt es. Zitat:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
Grundsätzlich sollte man aber immer ein eigenes FormatSettings kreieren, dann klappts auch mit dem Multithreading. |
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Man kann (oder zumindest habe ich es bis jetzt noch nicht geschafft) in Records zu schreiben. GetValue legt immer eine neue Kopie an. Auch mit TValue.MakeWithoutCopy funktioniert es nicht. Bislang habe ich im Internet auch keine Informationen gefunden woran es liegt.
Ja FormatSettings ist Global. Ein Record das auch verschiedene Funktionen zur Verfügung stellt. Soweit ich gesehen habe kein SingleTon und auch nicht Threadsicher. Ich lade gleich das Update hoch... eine Minute noch... |
AW: TEasyLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Update ist Online
|
AW: TEasyLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Das waren aber 12 Minuten :mrgreen:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
|
AW: TLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
Zitat:
|
AW: TEasyLinq<T>, eine generische Liste die einfache SQL Befehle ausführt
neues Update hinzugefügt...
|
AW: EasyLINQ, eine generische Liste die einfache SQL Befehle ausführt
Neues Update...
|
AW: EasyLINQ, eine generische Liste die einfache SQL Befehle ausführt
Liste der Anhänge anzeigen (Anzahl: 1)
Update...
|
AW: EasyLINQ, eine generische Liste die einfache SQL Befehle ausführt
Vielen Dank Daniela, sieht ja gut aus :)
Grüsse DSP |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz