Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

OnChange search query

[es] :: Pascal / Delphi / Kylix :: OnChange search query

[ Pregleda: 1221 | Odgovora: 12 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

delfi1122

Član broj: 340998
Poruke: 5
93.140.126.*



Profil

icon OnChange search query25.09.2019. u 08:46 - pre 54 meseci
Lijepi pozdrav svima,
radi se o delphi 7. Imam search query koji radi na OnChange event text box-a. Pošto ima puno recorda, to u mreži zna biti sporo. Pronašao sam ovo rješenje, ali ne znam složiti thread, molim vas ako mi netko može pomoći.
Koliko sam shvatio trebalo bi onchange dio staviti u thread.

https://stackoverflow.com/questions/26573267/delphi-delay-processing-if-user-still-typing

Znači primjer:

Code:
procedure btnOnChange..
begin

dataset.close;
dataset.selectsql.text := 'select n from table where field = :parameter';
params[0].asstring := bttext.text;
dataset.open

end;


Hvala svima.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: OnChange search query25.09.2019. u 09:02 - pre 54 meseci
> radi se o delphi 7. Imam search query koji radi na OnChange event text box-a. Pošto ima puno recorda, to u mreži zna biti sporo.

O kom broju se radi?

> Pronašao sam ovo rješenje, ali ne znam složiti thread, molim vas ako mi netko može pomoći.
> Koliko sam shvatio trebalo bi onchange dio staviti u thread.

Zapravo moras imati poseban/nezavisan thread (a mozda i vise njih) koji ce primati query za izvrsavanje iz OnChangea i slati dobijene rezultate natrag u glavni thread (da se prikazu korisniku). Koju bazu koristis i komponente za pristup bazi, da li su komponente threadsafe ili ne? Ako nisu onda moras imati za svaki thread odvojenu konekciju ka bazi (uglavnom posebna TDatabase komponenta).

 
Odgovor na temu

delfi1122

Član broj: 340998
Poruke: 5
93.140.126.*



Profil

icon Re: OnChange search query25.09.2019. u 09:30 - pre 54 meseci
Citat:
savkic: > radi se o delphi 7. Imam search query koji radi na OnChange event text box-a. Pošto ima puno recorda, to u mreži zna biti sporo.

O kom broju se radi?

> Pronašao sam ovo rješenje, ali ne znam složiti thread, molim vas ako mi netko može pomoći.
> Koliko sam shvatio trebalo bi onchange dio staviti u thread.

Zapravo moras imati poseban/nezavisan thread (a mozda i vise njih) koji ce primati query za izvrsavanje iz OnChangea i slati dobijene rezultate natrag u glavni thread (da se prikazu korisniku). Koju bazu koristis i komponente za pristup bazi, da li su komponente threadsafe ili ne? Ako nisu onda moras imati za svaki thread odvojenu konekciju ka bazi (uglavnom posebna TDatabase komponenta).


cca 20 000 recorda.

FIBPlus, mislim da nisu thread safe. baza je firebird
u principu prikazuje rezultate queryja u db gridu.
Znam da pitam puno, ali može primjer kako bi mogao napisati taj tread?
 
Odgovor na temu

_deran_

Član broj: 69493
Poruke: 252
91.232.237.*



+1 Profil

icon Re: OnChange search query25.09.2019. u 11:58 - pre 54 meseci
Ako je to neka pretraga (npr. autocomplete za listu artikala) nepotrebno je vraćati svih 20.000 rekorda, neka ti upit vrati prvih 100-200
Nisam siguran da li FIBPlus može da prekine izvršavanje upita. Ako otkucaš 10 slova to će poterati 10 upita koji vraćaju 20.000 slogova (ili 100 ako ograničiš). Trebalo bi na svaki novi sql upit prekinuti stare.

Po meni je bolje rešenje napraviti nešto sa TTimer-om, tipa kad se završi kucanje (desi se pauza od pola sekunde u kucanju) onda okinuti upit. Može i to sa thread-om umesto timera da se reši ali svakako korisnik neće ništa drugo raditi dok kuca slova za pretragu, pa nema potrebe da se okida pozadinski. Ne volim baš TTimer da koristim ali ako nema mnogo polja za pretragu ovde može dobro da odradi posao (samo da odloži okidanje upita na bazu dok korisnik kuca)
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4901
*.static.isp.telekom.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: OnChange search query25.09.2019. u 12:53 - pre 54 meseci
Na linku koji si ostavio, ideja sa tajmerom ti verovatno zavrsava posao. Pokusaj.

Kod je C++, ali je VCL pa ces lako prepraviti "strelice u tackice", "true" u "True" i sl.

Code:

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
   // tajmer interval za ovaj event je recimo 0.5 sec (500)
   Timer1->Enabled = false;
   
   // OVDE RASPALI SVOJ UPIT, JA SAM STAVIO DA SE SADRZAJ EDITA PREPISE NA CAPTION, RADI TESTIRANJA TRENUTKA KADA SE TEKST PROSDLEDJUJE NA IZVRSENJE
   Caption = "Query: " + Edit1->Text;


   Sleep(200);
}
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
   // resetuje se tajmer
   Timer1->Enabled = false;
   Timer1->Enabled = true;
}
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
82.117.201.26



+1064 Profil

icon Re: OnChange search query25.09.2019. u 14:01 - pre 54 meseci
Mislim da se windows timer procedure pozivaju sinhrono, tj hvataju se u win proc-u kao i bilo koji drugi event, no neka me neko ispravi.

 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: OnChange search query25.09.2019. u 14:07 - pre 54 meseci
> cca 20 000 recorda.

To nije nista, slobodno ih sve prevuci i filtriraj rucno (ili putem TDataset.Filter propertija).

> FIBPlus, mislim da nisu thread safe. baza je firebird
> u principu prikazuje rezultate queryja u db gridu.

To eventualno moze biti problem posto se sadrzaj vuce iz dataseta koji je u drugom threadu.

> Znam da pitam puno, ali može primjer kako bi mogao napisati taj tread?

Otprilike

Code:

 TMyThread = class(TThread)
  private
    FDB: TDatabase;
    FQuery: TQuery;
    FEvent: TEvent;

    FSQL: string;

    procedure ProcessSQL;
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;

    procedure ScheduleSQL(const ASQL: string);
    function GetResQuery: TQuery;

    procedure Finish;
  end;

{ TMyThread }

constructor TMyThread.Create;
begin
  inherited Create(False);
  FEvent := TEvent.Create;  
end;

destructor TMyThread.Destroy;
begin
  FEvent.Free;
  FDB.Free;  
  FQuery.Free;
    
  inherited Destroy;
end;

procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    if FEvent.WaitFor(INFINITE) = wrSignaled then 
    begin
      FEvent.ResetEvent;
      ProcessSQL;
    end;    
  end;
end;

procedure TBackgroundProcessor.Finish;
begin
  Terminate;
  FEvent.SetEvent;
  // Wait for thread to finish (but not indefinitelly) and release it.
  if WaitForSingleObject(Handle, 1200) = WAIT_OBJECT_0 then
    Free;
end;

procedure TMyThread.ProcessSQL;
begin
  if FSQL = '' then
    Exit;

  FDB := TDatabase.Create; // Kod da se napravi db komponenta i poveze na bazu
  FQuery := TQuery.Craete(FDB); // Kod da se napravi query i poveze na FDB
  FQuery.SQL := FSQL;
  FQuery.Execute;

  while not FQuery.Eof do  // Prevuci sve podatke
    FQuery.Next; 
  
  PostMessage(Application.MainForm.Handle, WM_APP, 1, 0); // Signaliziramo da je kveri spreman
end;

procedure TMyThread.ScheduleSQL(const ASQL: string);
begin
  FSQL := ASQL;
  FEvent.SetEvent;
end;

function TMyThread.GetResQuery: TQuery;
begin  
  Result := FQuery;
  FQuery := nil; // Da se vise ne moze koristiti iz ovog threada
end;

glavni thread/forma.

TfrmMain = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
private
  FQuery: TQuery;
  FMyThread: TMyThread;
public
  procedure WMApp(var Message: TMessage); message WM_APP;
end;

TfrmMain.WMApp(var Message: TMessage); message WM_APP;
begin
  FQuery := FMyThread.GetResQuery;
  Datasource.DAtaset := FQuery;
  DBGrid.Datasource := DataSource;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FMyThread := TMyThread.Create;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  FMyThread.Finish;
end;

A u OnChangu stavi FThread.ScheduleSQL('select * from tabela');

Ako ova varijanta (sa pravljenjem u jednom threadu a koriscenjem u drugom ne radi) onda vidi da kopiras podatke u neki pomocni dataset, tipa TClientDataset.

 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
82.117.201.26



+1064 Profil

icon Re: OnChange search query25.09.2019. u 14:28 - pre 54 meseci
Nit pick, ukoliko ulete dva onchange poziva dok se jedan izvrsava moze doci do problema. Treba staviti
da onchange saceka da se prethodni queue zavrsi.
 
Odgovor na temu

_deran_

Član broj: 69493
Poruke: 252
91.232.237.*



+1 Profil

icon Re: OnChange search query25.09.2019. u 14:36 - pre 54 meseci
Citat:
Branimir Maksimovic: Nit pick, ukoliko ulete dva onchange poziva dok se jedan izvrsava moze doci do problema. Treba staviti
da onchange saceka da se prethodni queue zavrsi.


Zar nije bolje da zaustavi prethodne upite i pobije thread-ove? Ako neko brzo kuca ima da se načeka do zadnjeg rezultata :)
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
82.117.201.26



+1064 Profil

icon Re: OnChange search query25.09.2019. u 14:47 - pre 54 meseci
Ma .regularno bi bilo da queue-uje requeste i najjednostavnije.
Povratna informacija takodje moze u queue. Onda taj sql thread moze
da se koristi za bilo kakav upit.
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: OnChange search query25.09.2019. u 15:00 - pre 54 meseci
> Mislim da se windows timer procedure pozivaju sinhrono, tj hvataju se u win proc-u kao i bilo koji drugi event, no neka me neko ispravi.

WM_TIMER je poruka niskog prioriteta, poput WM_PAINT i bice izvrsena samo ako nema drugih poruka viseg prioriteta. Zavisno od opterecenja programa, Timer event se moze pozivati tacno na vreme ili potpuno random.
 
Odgovor na temu

delfi1122

Član broj: 340998
Poruke: 5
93.140.94.*



Profil

icon Re: OnChange search query26.09.2019. u 11:13 - pre 54 meseci
Sa timerom rješio, nije loše makar se malo vidi delay.
Probam rješenje od savkica sa threadom i javim.
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4901
*.static.isp.telekom.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: OnChange search query26.09.2019. u 11:19 - pre 54 meseci
Samo izbaci onaj Sleep(200), on je visak, njega sam stavio valjda kao simulacija trajanja upita, ne secam se.

Vidi, taj kod sa tajmerom ti sigurno zavrsava posao, puno puta je koriscen u praksi u slicnim situacijama, iako se i meni licno ne svidja jer "nije programerski". Thread je tehnicki ispravnije resenje, pod uslovom da je pravilno uradjen i da sama biblioteka ne boluje od nekih thread bolesti za koje se ne zna.
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: OnChange search query

[ Pregleda: 1221 | Odgovora: 12 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.