fields.inc 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. TFields and related components implementations.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. Procedure DumpMem (P : Pointer;Size : Longint);
  13. Var i : longint;
  14. begin
  15. Write ('Memory dump : ');
  16. For I:=0 to Size-1 do
  17. Write (Pbyte(P)[i],' ');
  18. Writeln;
  19. end;
  20. { ---------------------------------------------------------------------
  21. TFieldDef
  22. ---------------------------------------------------------------------}
  23. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  24. ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Longint);
  25. begin
  26. Inherited Create(AOwner);
  27. {$ifdef dsdebug }
  28. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  29. {$endif}
  30. FName:=Aname;
  31. FDisplayName := '';
  32. FDatatype:=ADatatype;
  33. FSize:=ASize;
  34. FRequired:=ARequired;
  35. FPrecision:=-1;
  36. // Correct sizes.
  37. If FDataType=ftFloat then
  38. begin
  39. If Not (FSize in [4,8,10]) then FSize:=10
  40. end
  41. else If FDataType in [ftWord,ftsmallint,ftinteger] Then
  42. If Not (byte(FSize) in [1,2,4]) then FSize:=4;
  43. FFieldNo:=AFieldNo;
  44. end;
  45. Destructor TFieldDef.Destroy;
  46. begin
  47. Inherited destroy;
  48. end;
  49. procedure TFieldDef.Assign(APersistent: TPersistent);
  50. var fd: TFieldDef;
  51. begin
  52. fd := nil;
  53. if APersistent is TFieldDef then
  54. fd := APersistent as TFieldDef;
  55. if Assigned(fd) then begin
  56. Collection.BeginUpdate;
  57. try
  58. Name := fd.Name;
  59. DataType := fd.DataType;
  60. Size := fd.Size;
  61. Precision := fd.Precision;
  62. FRequired := fd.Required;
  63. finally
  64. Collection.EndUpdate;
  65. end;
  66. end else
  67. inherited Assign(APersistent);
  68. end;
  69. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  70. Var TheField : TFieldClass;
  71. begin
  72. {$ifdef dsdebug}
  73. Writeln ('Creating field '+FNAME);
  74. {$endif dsdebug}
  75. TheField:=GetFieldClass;
  76. if TheField=Nil then
  77. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  78. Result:=Thefield.Create(AOwner);
  79. Try
  80. Result.Size:=FSize;
  81. Result.Required:=FRequired;
  82. Result.FFieldName:=FName;
  83. Result.FDisplayLabel:=FDisplayName;
  84. Result.FFieldNo:=Self.FieldNo;
  85. Result.SetFieldType(DataType);
  86. Result.FReadOnly:= (faReadOnly in Attributes);
  87. {$ifdef dsdebug}
  88. Writeln ('TFieldDef.CReateField : Trying to set dataset');
  89. {$endif dsdebug}
  90. {$ifdef dsdebug}
  91. Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo);
  92. {$endif dsdebug}
  93. Result.Dataset:=TFieldDefs(Collection).Dataset;
  94. If Result is TFloatField then
  95. TFloatField(Result).Precision:=FPrecision;
  96. except
  97. Result.Free;
  98. Raise;
  99. end;
  100. end;
  101. procedure TFieldDef.SetAttributes(AValue: TFieldAttributes);
  102. begin
  103. FAttributes := AValue;
  104. Changed(False);
  105. end;
  106. procedure TFieldDef.SetDataType(AValue: TFieldType);
  107. begin
  108. FDataType := AValue;
  109. Changed(False);
  110. end;
  111. procedure TFieldDef.SetPrecision(const AValue: Longint);
  112. begin
  113. FPrecision := AValue;
  114. Changed(False);
  115. end;
  116. procedure TFieldDef.SetSize(const AValue: Word);
  117. begin
  118. FSize := AValue;
  119. Changed(False);
  120. end;
  121. function TFieldDef.GetDisplayName: string;
  122. begin
  123. Result := FDisplayName;
  124. if Result = '' then
  125. Result := Fname;
  126. end;
  127. procedure TFieldDef.SetDisplayName(const AValue: string);
  128. begin
  129. if (AValue <> '') and (AnsiCompareText(AValue, DisplayName) <> 0) and
  130. (Collection is TOwnedCollection) and
  131. (TFieldDefs(Collection).IndexOf(AValue) >= 0) then
  132. DatabaseErrorFmt(SDuplicateName, [AValue, Collection.ClassName]);
  133. FName := AValue;
  134. end;
  135. Function TFieldDef.GetFieldClass : TFieldClass;
  136. begin
  137. //!! Should be owner as tdataset but that doesn't work ??
  138. If Assigned(Collection) And
  139. (Collection is TFieldDefs) And
  140. Assigned(TFieldDefs(Collection).Dataset) then
  141. Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType)
  142. else
  143. Result:=Nil;
  144. end;
  145. { ---------------------------------------------------------------------
  146. TFieldDefs
  147. ---------------------------------------------------------------------}
  148. {
  149. destructor TFieldDefs.Destroy;
  150. begin
  151. FItems.Free;
  152. // This will destroy all fielddefs since we own them...
  153. Inherited Destroy;
  154. end;
  155. }
  156. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType);
  157. begin
  158. Add(AName,ADatatype,0,False);
  159. end;
  160. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word);
  161. begin
  162. Add(AName,ADatatype,ASize,False);
  163. end;
  164. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  165. ARequired: Boolean);
  166. begin
  167. If Length(AName)=0 Then
  168. DatabaseError(SNeedFieldName);
  169. // the fielddef will register itself here as a owned component.
  170. // fieldno is 1 based !
  171. BeginUpdate;
  172. try
  173. TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,Count+1);
  174. finally
  175. EndUpdate;
  176. end;
  177. end;
  178. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  179. begin
  180. Result := TFieldDef(inherited Items[Index]);;
  181. end;
  182. function TFieldDefs.GetDataset: TDataset;
  183. begin
  184. Result := TDataset(GetOwner);
  185. end;
  186. procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef);
  187. begin
  188. inherited Items[Index] := AValue;
  189. end;
  190. procedure TFieldDefs.SetItemName(AItem: TCollectionItem);
  191. begin
  192. if AItem is TFieldDef then
  193. with AItem as TFieldDef do
  194. if Name = '' then
  195. Name := Dataset.Name + Copy(ClassName, 2, 5) + IntToStr(ID+1)
  196. else inherited SetItemName(AItem);
  197. end;
  198. constructor TFieldDefs.Create(ADataset: TDataset);
  199. begin
  200. Inherited Create(TPersistent(ADataset), TFieldDef);
  201. end;
  202. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  203. Var I : longint;
  204. begin
  205. Clear;
  206. For i:=0 to FieldDefs.Count-1 do
  207. With FieldDefs[i] do
  208. Add(Name,DataType,Size,Required);
  209. end;
  210. {
  211. procedure TFieldDefs.Clear;
  212. Var I : longint;
  213. begin
  214. For I:=FItems.Count-1 downto 0 do
  215. TFieldDef(Fitems[i]).Free;
  216. FItems.Clear;
  217. end;
  218. }
  219. function TFieldDefs.Find(const AName: string): TFieldDef;
  220. Var I : longint;
  221. begin
  222. I:=IndexOf(AName);
  223. If I=-1 Then
  224. DataBaseErrorFmt(SUnknownField,[AName,DataSet.Name]);
  225. Result:=Items[i];
  226. end;
  227. function TFieldDefs.IndexOf(const AName: string): Longint;
  228. Var I : longint;
  229. begin
  230. For I:=0 to Count-1 do
  231. If AnsiCompareText(Items[I].Name,AName)=0 then
  232. begin
  233. Result:=I;
  234. Exit;
  235. end;
  236. Result:=-1;
  237. end;
  238. procedure TFieldDefs.Update;
  239. begin
  240. DataSet.InitFieldDefs;
  241. end;
  242. Function TFieldDefs.AddFieldDef : TFieldDef;
  243. begin
  244. Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,Count+1);
  245. end;
  246. { ---------------------------------------------------------------------
  247. TField
  248. ---------------------------------------------------------------------}
  249. Const
  250. SBoolean = 'Boolean';
  251. SDateTime = 'TDateTime';
  252. SFloat = 'Float';
  253. SInteger = 'Integer';
  254. SVariant = 'Variant';
  255. SString = 'String';
  256. constructor TField.Create(AOwner: TComponent);
  257. begin
  258. Inherited Create(AOwner);
  259. FVisible:=True;
  260. FValidChars:=[#0..#255];
  261. FProviderFlags := [pfInUpdate,pfInWhere];
  262. end;
  263. destructor TField.Destroy;
  264. begin
  265. IF Assigned(FDataSet) then
  266. begin
  267. FDataSet.Active:=False;
  268. if Assigned(FFields) then
  269. FFields.Remove(Self);
  270. end;
  271. FLookupList.Free;
  272. Inherited Destroy;
  273. end;
  274. function TField.AccessError(const TypeName: string): EDatabaseError;
  275. begin
  276. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  277. end;
  278. procedure TField.Assign(Source: TPersistent);
  279. begin
  280. if Source = nil then Clear
  281. else if Source is TField then begin
  282. Value := TField(Source).Value;
  283. end else
  284. inherited Assign(Source);
  285. end;
  286. procedure TField.AssignValue(const Value: TVarRec);
  287. procedure Error;
  288. begin
  289. DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  290. end;
  291. begin
  292. with Value do
  293. case VType of
  294. vtInteger:
  295. AsInteger := VInteger;
  296. vtBoolean:
  297. AsBoolean := VBoolean;
  298. vtChar:
  299. AsString := VChar;
  300. vtExtended:
  301. AsFloat := VExtended^;
  302. vtString:
  303. AsString := VString^;
  304. vtPointer:
  305. if VPointer <> nil then Error;
  306. vtPChar:
  307. AsString := VPChar;
  308. vtObject:
  309. if (VObject = nil) or (VObject is TPersistent) then
  310. Assign(TPersistent(VObject))
  311. else
  312. Error;
  313. vtAnsiString:
  314. AsString := string(VAnsiString);
  315. // vtCurrency:
  316. // AsCurrency := VCurrency^;
  317. vtVariant:
  318. if not VarIsClear(VVariant^) then Self.Value := VVariant^;
  319. vtWideString:
  320. AsString := WideString(VWideString);
  321. vtInt64:
  322. Self.Value := VInt64^;
  323. else
  324. Error;
  325. end;
  326. end;
  327. procedure TField.Change;
  328. begin
  329. If Assigned(FOnChange) Then
  330. FOnChange(Self);
  331. end;
  332. procedure TField.CheckInactive;
  333. begin
  334. If Assigned(FDataSet) then
  335. FDataset.CheckInactive;
  336. end;
  337. procedure TField.Clear;
  338. begin
  339. if FieldKind in [fkData, fkInternalCalc] then
  340. SetData(Nil);
  341. end;
  342. procedure TField.DataChanged;
  343. begin
  344. FDataset.DataEvent(deFieldChange,ptrint(Self));
  345. end;
  346. procedure TField.FocusControl;
  347. begin
  348. FDataSet.DataEvent(deFocusControl,ptrint(Self));
  349. end;
  350. procedure TField.FreeBuffers;
  351. begin
  352. // Empty. Provided for backward compatibiliy;
  353. // TDataset manages the buffers.
  354. end;
  355. function TField.GetAsBoolean: Boolean;
  356. begin
  357. AccessError(SBoolean);
  358. end;
  359. function TField.GetAsDateTime: TDateTime;
  360. begin
  361. AccessError(SdateTime);
  362. end;
  363. function TField.GetAsFloat: Double;
  364. begin
  365. AccessError(SDateTime);
  366. end;
  367. function TField.GetAsLongint: Longint;
  368. begin
  369. AccessError(SInteger);
  370. end;
  371. function TField.GetAsVariant: Variant;
  372. begin
  373. AccessError(SVariant);
  374. end;
  375. function TField.GetAsInteger: Integer;
  376. begin
  377. Result:=GetAsLongint;
  378. end;
  379. function TField.GetAsString: string;
  380. begin
  381. AccessError(SString);
  382. end;
  383. function TField.GetOldValue: Variant;
  384. var SaveState : TDatasetState;
  385. begin
  386. SaveState := FDataset.State;
  387. try
  388. FDataset.SetTempState(dsOldValue);
  389. Result := GetAsVariant;
  390. finally
  391. FDataset.RestoreState(SaveState);
  392. end;
  393. end;
  394. function TField.GetNewValue: Variant;
  395. var SaveState : TDatasetState;
  396. begin
  397. SaveState := FDataset.State;
  398. try
  399. FDataset.SetTempState(dsNewValue);
  400. Result := GetAsVariant;
  401. finally
  402. FDataset.RestoreState(SaveState);
  403. end;
  404. end;
  405. procedure TField.SetNewValue(const AValue: Variant);
  406. var SaveState : TDatasetState;
  407. begin
  408. SaveState := FDataset.State;
  409. try
  410. FDataset.SetTempState(dsNewValue);
  411. SetAsVariant(AValue);
  412. finally
  413. FDataset.RestoreState(SaveState);
  414. end;
  415. end;
  416. function TField.GetCurValue: Variant;
  417. var SaveState : TDatasetState;
  418. begin
  419. SaveState := FDataset.State;
  420. try
  421. FDataset.SetTempState(dsCurValue);
  422. Result := GetAsVariant;
  423. finally
  424. FDataset.RestoreState(SaveState);
  425. end;
  426. end;
  427. function TField.GetCanModify: Boolean;
  428. begin
  429. Result:=Not ReadOnly;
  430. If Result then
  431. begin
  432. Result:=Assigned(DataSet);
  433. If Result then
  434. Result:= DataSet.CanModify;
  435. end;
  436. end;
  437. function TField.GetData(Buffer: Pointer): Boolean;
  438. begin
  439. IF FDataset=Nil then
  440. DatabaseErrorFmt(SNoDataset,[FieldName]);
  441. If FVAlidating then
  442. begin
  443. result:=Not(FValueBuffer=Nil);
  444. If Result then
  445. Move (FValueBuffer^,Buffer^ ,DataSize);
  446. end
  447. else
  448. Result:=FDataset.GetFieldData(Self,Buffer);
  449. end;
  450. function TField.GetDataSize: Word;
  451. begin
  452. Result:=0;
  453. end;
  454. function TField.GetDefaultWidth: Longint;
  455. begin
  456. Result:=10;
  457. end;
  458. function TField.GetDisplayName : String;
  459. begin
  460. If FDisplayLabel<>'' then
  461. result:=FDisplayLabel
  462. else
  463. Result:=FFieldName;
  464. end;
  465. Function TField.IsDisplayStored : Boolean;
  466. begin
  467. Result:=(DisplayLabel<>FieldName);
  468. end;
  469. function TField.GetLookupList: TLookupList;
  470. begin
  471. if not Assigned(FLookupList) then
  472. FLookupList := TLookupList.Create;
  473. Result := FLookupList;
  474. end;
  475. procedure TField.CalcLookupValue;
  476. begin
  477. if FLookupCache then
  478. Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
  479. else if (FLookupDataSet <> nil) and FLookupDataSet.Active then
  480. Value := FLookupDataSet.Lookup(FLookupKeyFields,
  481. FDataSet.FieldValues[FKeyFields], FLookupResultField);
  482. end;
  483. function TField.getIndex : longint;
  484. begin
  485. If Assigned(FDataset) then
  486. Result:=FDataset.FFieldList.IndexOf(Self)
  487. else
  488. Result:=-1;
  489. end;
  490. function TField.GetAsCurrency: Currency;
  491. begin
  492. Result := GetAsFloat;
  493. end;
  494. procedure TField.SetAlignment(const AValue: TAlignMent);
  495. begin
  496. if FAlignment <> AValue then
  497. begin
  498. FAlignment := Avalue;
  499. PropertyChanged(false);
  500. end;
  501. end;
  502. procedure TField.SetIndex(AValue: Integer);
  503. begin
  504. if FFields <> nil then FFields.SetFieldIndex(Self, AValue)
  505. end;
  506. procedure TField.SetAsCurrency(AValue: Currency);
  507. begin
  508. SetAsFloat(AValue);
  509. end;
  510. function TField.GetIsNull: Boolean;
  511. begin
  512. Result:=Not(GetData (Nil));
  513. end;
  514. function TField.GetParentComponent: TComponent;
  515. begin
  516. Result := DataSet;
  517. end;
  518. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  519. begin
  520. AText:=GetAsString;
  521. end;
  522. function TField.HasParent: Boolean;
  523. begin
  524. HasParent:=True;
  525. end;
  526. function TField.IsValidChar(InputChar: Char): Boolean;
  527. begin
  528. // FValidChars must be set in Create.
  529. Result:=InputChar in FValidChars;
  530. end;
  531. procedure TField.RefreshLookupList;
  532. var SaveActive: Boolean;
  533. begin
  534. if (FLookupDataSet <> nil) And (FLookupKeyFields <> '') And
  535. (FlookupResultField <> '') And (FKeyFields <> '') then begin
  536. SaveActive := FLookupDataSet.Active;
  537. with FLookupDataSet do
  538. try
  539. Active := True;
  540. FFields.CheckFieldNames(FLookupKeyFields);
  541. FieldByName(FLookupResultField);
  542. LookupList.Clear;
  543. DisableControls;
  544. try
  545. First;
  546. while not Eof do begin
  547. FLookupList.Add(FieldValues[FLookupKeyFields],
  548. FieldValues[FLookupResultField]);
  549. Next;
  550. end;
  551. finally
  552. EnableControls;
  553. end;
  554. finally
  555. Active := SaveActive;
  556. end;
  557. end;
  558. end;
  559. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  560. begin
  561. Inherited Notification(AComponent,Operation);
  562. if (Operation = opRemove) and (AComponent = FLookupDataSet) then
  563. FLookupDataSet := nil;
  564. end;
  565. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  566. begin
  567. If (FDataset<>Nil) and (FDataset.Active) then
  568. If LayoutAffected then
  569. FDataset.DataEvent(deLayoutChange,0)
  570. else
  571. FDataset.DataEvent(deDatasetchange,0);
  572. end;
  573. procedure TField.ReadState(Reader: TReader);
  574. begin
  575. inherited ReadState(Reader);
  576. if Reader.Parent is TDataSet then
  577. DataSet := TDataSet(Reader.Parent);
  578. end;
  579. procedure TField.SetAsBoolean(AValue: Boolean);
  580. begin
  581. AccessError(SBoolean);
  582. end;
  583. procedure TField.SetAsDateTime(AValue: TDateTime);
  584. begin
  585. AccessError(SDateTime);
  586. end;
  587. procedure TField.SetAsFloat(AValue: Double);
  588. begin
  589. AccessError(SFloat);
  590. end;
  591. procedure TField.SetAsVariant(AValue: Variant);
  592. begin
  593. if VarIsNull(AValue) then
  594. Clear
  595. else
  596. try
  597. SetVarValue(AValue);
  598. except
  599. on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]);
  600. end;
  601. end;
  602. procedure TField.SetAsLongint(AValue: Longint);
  603. begin
  604. AccessError(SInteger);
  605. end;
  606. procedure TField.SetAsInteger(AValue: Integer);
  607. begin
  608. SetAsLongint(AValue);
  609. end;
  610. procedure TField.SetAsString(const AValue: string);
  611. begin
  612. AccessError(SString);
  613. end;
  614. procedure TField.SetData(Buffer: Pointer);
  615. begin
  616. If Not Assigned(FDataset) then
  617. EDatabaseError.CreateFmt(SNoDataset,[FieldName]);
  618. FDataSet.SetFieldData(Self,Buffer, False);
  619. end;
  620. Procedure TField.SetDataset (Value : TDataset);
  621. begin
  622. {$ifdef dsdebug}
  623. Writeln ('Setting dataset');
  624. {$endif}
  625. If Value=FDataset then exit;
  626. If Assigned(FDataset) Then
  627. begin
  628. FDataset.CheckInactive;
  629. FDataset.FFieldList.Remove(Self);
  630. end;
  631. If Assigned(Value) then
  632. begin
  633. Value.CheckInactive;
  634. Value.FFieldList.Add(Self);
  635. end;
  636. FDataset:=Value;
  637. end;
  638. procedure TField.SetDataType(AValue: TFieldType);
  639. begin
  640. FDataType := AValue;
  641. end;
  642. procedure TField.SetFieldType(AValue: TFieldType);
  643. begin
  644. //!! To be implemented
  645. end;
  646. procedure TField.SetParentComponent(AParent: TComponent);
  647. begin
  648. if not (csLoading in ComponentState) then
  649. DataSet := AParent as TDataSet;
  650. end;
  651. procedure TField.SetSize(AValue: Word);
  652. begin
  653. CheckInactive;
  654. CheckTypeSize(AValue);
  655. FSize:=AValue;
  656. end;
  657. procedure TField.SetText(const AValue: string);
  658. begin
  659. AsString:=AValue;
  660. end;
  661. procedure TField.SetVarValue(const AValue: Variant);
  662. begin
  663. AccessError(SVariant);
  664. end;
  665. procedure TField.Validate(Buffer: Pointer);
  666. begin
  667. If assigned(OnValidate) Then
  668. begin
  669. FValueBuffer:=Buffer;
  670. FValidating:=True;
  671. Try
  672. OnValidate(Self);
  673. finally
  674. FValidating:=False;
  675. end;
  676. end;
  677. end;
  678. class function Tfield.IsBlob: Boolean;
  679. begin
  680. Result:=False;
  681. end;
  682. class procedure TField.CheckTypeSize(AValue: Longint);
  683. begin
  684. If (AValue<>0) and Not IsBlob Then
  685. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  686. end;
  687. // TField private methods
  688. function TField.GetDisplayText: String;
  689. begin
  690. SetLength(Result, 0);
  691. if Assigned(OnGetText) then
  692. OnGetText(Self, Result, True)
  693. else
  694. GetText(Result, True);
  695. end;
  696. procedure TField.SetDisplayLabel(const AValue: string);
  697. begin
  698. if FDisplayLabel<>Avalue then
  699. begin
  700. FDisplayLabel:=Avalue;
  701. PropertyChanged(true);
  702. end;
  703. end;
  704. procedure TField.SetDisplayWidth(const AValue: Longint);
  705. begin
  706. if FDisplayWidth<>AValue then
  707. begin
  708. FDisplayWidth:=AValue;
  709. PropertyChanged(True);
  710. end;
  711. end;
  712. function TField.GetDisplayWidth: integer;
  713. begin
  714. if FDisplayWidth=0 then
  715. result:=GetDefaultWidth
  716. else
  717. result:=FDisplayWidth;
  718. end;
  719. procedure TField.SetReadOnly(const AValue: Boolean);
  720. begin
  721. if (FReadOnly<>Avalue) then
  722. begin
  723. FReadOnly:=AValue;
  724. PropertyChanged(True);
  725. end;
  726. end;
  727. procedure TField.SetVisible(const AValue: Boolean);
  728. begin
  729. if FVisible<>Avalue then
  730. begin
  731. FVisible:=AValue;
  732. PropertyChanged(True);
  733. end;
  734. end;
  735. { ---------------------------------------------------------------------
  736. TStringField
  737. ---------------------------------------------------------------------}
  738. constructor TStringField.Create(AOwner: TComponent);
  739. begin
  740. Inherited Create(AOwner);
  741. SetDataType(ftString);
  742. Size:=20;
  743. end;
  744. class procedure TStringField.CheckTypeSize(AValue: Longint);
  745. begin
  746. If (AValue<1) or (AValue>dsMaxStringSize) Then
  747. databaseErrorFmt(SInvalidFieldSize,[AValue])
  748. end;
  749. function TStringField.GetAsBoolean: Boolean;
  750. Var S : String;
  751. begin
  752. S:=GetAsString;
  753. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  754. end;
  755. function TStringField.GetAsDateTime: TDateTime;
  756. begin
  757. Result:=StrToDateTime(GetAsString);
  758. end;
  759. function TStringField.GetAsFloat: Double;
  760. begin
  761. Result:=StrToFloat(GetAsString);
  762. end;
  763. function TStringField.GetAsLongint: Longint;
  764. begin
  765. Result:=StrToInt(GetAsString);
  766. end;
  767. function TStringField.GetAsString: string;
  768. begin
  769. If Not GetValue(Result) then
  770. Result:='';
  771. end;
  772. function TStringField.GetAsVariant: Variant;
  773. Var s : string;
  774. begin
  775. If GetValue(s) then
  776. Result:=s
  777. else
  778. Result:=Null;
  779. end;
  780. function TStringField.GetDataSize: Word;
  781. begin
  782. Result:=Size+1;
  783. end;
  784. function TStringField.GetDefaultWidth: Longint;
  785. begin
  786. result:=Size;
  787. end;
  788. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  789. begin
  790. AText:=GetAsString;
  791. end;
  792. function TStringField.GetValue(var AValue: string): Boolean;
  793. Var Buf : TStringFieldBuffer;
  794. begin
  795. Result:=GetData(@Buf);
  796. If Result then
  797. AValue:=Buf;
  798. end;
  799. procedure TStringField.SetAsBoolean(AValue: Boolean);
  800. begin
  801. If AValue Then
  802. SetAsString('T')
  803. else
  804. SetAsString('F');
  805. end;
  806. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  807. begin
  808. SetAsString(DateTimeToStr(AValue));
  809. end;
  810. procedure TStringField.SetAsFloat(AValue: Double);
  811. begin
  812. SetAsString(FloatToStr(AValue));
  813. end;
  814. procedure TStringField.SetAsLongint(AValue: Longint);
  815. begin
  816. SetAsString(intToStr(AValue));
  817. end;
  818. procedure TStringField.SetAsString(const AValue: string);
  819. Const NullByte : char = #0;
  820. begin
  821. IF Length(AValue)=0 then
  822. SetData(@NullByte)
  823. else
  824. SetData(@AValue[1]);
  825. end;
  826. procedure TStringField.SetVarValue(const AValue: Variant);
  827. begin
  828. SetAsString(AValue);
  829. end;
  830. { ---------------------------------------------------------------------
  831. TNumericField
  832. ---------------------------------------------------------------------}
  833. constructor TNumericField.Create(AOwner: TComponent);
  834. begin
  835. Inherited Create(AOwner);
  836. AlignMent:=taRightJustify;
  837. end;
  838. procedure TNumericField.RangeError(AValue, Min, Max: Double);
  839. begin
  840. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  841. end;
  842. procedure TNumericField.SetDisplayFormat(const AValue: string);
  843. begin
  844. If FDisplayFormat<>AValue then
  845. begin
  846. FDisplayFormat:=AValue;
  847. PropertyChanged(True);
  848. end;
  849. end;
  850. procedure TNumericField.SetEditFormat(const AValue: string);
  851. begin
  852. If FEDitFormat<>AValue then
  853. begin
  854. FEDitFormat:=AVAlue;
  855. PropertyChanged(True);
  856. end;
  857. end;
  858. { ---------------------------------------------------------------------
  859. TLongintField
  860. ---------------------------------------------------------------------}
  861. constructor TLongintField.Create(AOwner: TComponent);
  862. begin
  863. Inherited Create(AOwner);
  864. SetDatatype(ftinteger);
  865. FMinRange:=Low(LongInt);
  866. FMaxRange:=High(LongInt);
  867. FValidchars:=['+','-','0'..'9'];
  868. end;
  869. function TLongintField.GetAsFloat: Double;
  870. begin
  871. Result:=GetAsLongint;
  872. end;
  873. function TLongintField.GetAsLongint: Longint;
  874. begin
  875. If Not GetValue(Result) then
  876. Result:=0;
  877. end;
  878. function TLongintField.GetAsVariant: Variant;
  879. Var L : Longint;
  880. begin
  881. If GetValue(L) then
  882. Result:=L
  883. else
  884. Result:=Null;
  885. end;
  886. function TLongintField.GetAsString: string;
  887. Var L : Longint;
  888. begin
  889. If GetValue(L) then
  890. Result:=IntTostr(L)
  891. else
  892. Result:='';
  893. end;
  894. function TLongintField.GetDataSize: Word;
  895. begin
  896. Result:=SizeOf(Longint);
  897. end;
  898. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  899. var l : longint;
  900. fmt : string;
  901. begin
  902. Atext:='';
  903. If Not GetValue(l) then exit;
  904. If ADisplayText or (FEditFormat='') then
  905. fmt:=FDisplayFormat
  906. else
  907. fmt:=FEditFormat;
  908. If length(fmt)<>0 then
  909. AText:=FormatFloat(fmt,L)
  910. else
  911. Str(L,AText);
  912. end;
  913. function TLongintField.GetValue(var AValue: Longint): Boolean;
  914. Var L : Longint;
  915. P : PLongint;
  916. begin
  917. P:=@L;
  918. Result:=GetData(P);
  919. If Result then
  920. Case Datatype of
  921. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  922. ftword : Avalue:=Pword(P)^;
  923. ftsmallint : AValue:=PSmallint(P)^;
  924. end;
  925. end;
  926. procedure TLongintField.SetAsFloat(AValue: Double);
  927. begin
  928. SetAsLongint(Round(Avalue));
  929. end;
  930. procedure TLongintField.SetAsLongint(AValue: Longint);
  931. begin
  932. If CheckRange(AValue) then
  933. SetData(@AValue)
  934. else
  935. RangeError(Avalue,FMinrange,FMaxRange);
  936. end;
  937. procedure TLongintField.SetVarValue(const AValue: Variant);
  938. begin
  939. SetAsLongint(AValue);
  940. end;
  941. procedure TLongintField.SetAsString(const AValue: string);
  942. Var L,Code : longint;
  943. begin
  944. If length(AValue)=0 then
  945. Clear
  946. else
  947. begin
  948. Val(AVAlue,L,Code);
  949. If Code=0 then
  950. SetAsLongint(L)
  951. else
  952. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  953. end;
  954. end;
  955. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  956. begin
  957. result := true;
  958. if (FMaxValue=0) then
  959. begin
  960. if (AValue>FMaxRange) Then result := false;
  961. end
  962. else
  963. if AValue>FMaxValue then result := false;
  964. if (FMinValue=0) then
  965. begin
  966. if (AValue<FMinRange) Then result := false;
  967. end
  968. else
  969. if AValue<FMinValue then result := false;
  970. end;
  971. Procedure TLongintField.SetMaxValue (AValue : longint);
  972. begin
  973. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  974. FMaxValue:=AValue
  975. else
  976. RangeError(AValue,FMinRange,FMaxRange);
  977. end;
  978. Procedure TLongintField.SetMinValue (AValue : longint);
  979. begin
  980. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  981. FMinValue:=AValue
  982. else
  983. RangeError(AValue,FMinRange,FMaxRange);
  984. end;
  985. { ---------------------------------------------------------------------
  986. TLargeintField
  987. ---------------------------------------------------------------------}
  988. constructor TLargeintField.Create(AOwner: TComponent);
  989. begin
  990. Inherited Create(AOwner);
  991. SetDatatype(ftLargeint);
  992. FMinRange:=Low(Largeint);
  993. FMaxRange:=High(Largeint);
  994. FValidchars:=['+','-','0'..'9'];
  995. end;
  996. function TLargeintField.GetAsFloat: Double;
  997. begin
  998. Result:=GetAsLargeint;
  999. end;
  1000. function TLargeintField.GetAsLargeint: Largeint;
  1001. begin
  1002. If Not GetValue(Result) then
  1003. Result:=0;
  1004. end;
  1005. function TLargeIntField.GetAsVariant: Variant;
  1006. Var L : Largeint;
  1007. begin
  1008. If GetValue(L) then
  1009. Result:=L
  1010. else
  1011. Result:=Null;
  1012. end;
  1013. function TLargeintField.GetAsLongint: Longint;
  1014. begin
  1015. Result:=GetAsLargeint;
  1016. end;
  1017. function TLargeintField.GetAsString: string;
  1018. Var L : Largeint;
  1019. begin
  1020. If GetValue(L) then
  1021. Result:=IntTostr(L)
  1022. else
  1023. Result:='';
  1024. end;
  1025. function TLargeintField.GetDataSize: Word;
  1026. begin
  1027. Result:=SizeOf(Largeint);
  1028. end;
  1029. procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean);
  1030. var l : largeint;
  1031. fmt : string;
  1032. begin
  1033. Atext:='';
  1034. If Not GetValue(l) then exit;
  1035. If ADisplayText or (FEditFormat='') then
  1036. fmt:=FDisplayFormat
  1037. else
  1038. fmt:=FEditFormat;
  1039. If length(fmt)<>0 then
  1040. AText:=FormatFloat(fmt,L)
  1041. else
  1042. Str(L,AText);
  1043. end;
  1044. function TLargeintField.GetValue(var AValue: Largeint): Boolean;
  1045. type
  1046. PLargeint = ^Largeint;
  1047. Var P : PLargeint;
  1048. begin
  1049. P:=@AValue;
  1050. Result:=GetData(P);
  1051. end;
  1052. procedure TLargeintField.SetAsFloat(AValue: Double);
  1053. begin
  1054. SetAsLargeint(Round(Avalue));
  1055. end;
  1056. procedure TLargeintField.SetAsLargeint(AValue: Largeint);
  1057. begin
  1058. If CheckRange(AValue) then
  1059. SetData(@AValue)
  1060. else
  1061. RangeError(Avalue,FMinrange,FMaxRange);
  1062. end;
  1063. procedure TLargeintField.SetAsLongint(AValue: Longint);
  1064. begin
  1065. SetAsLargeint(Avalue);
  1066. end;
  1067. procedure TLargeintField.SetAsString(const AValue: string);
  1068. Var L : largeint;
  1069. code : longint;
  1070. begin
  1071. If length(AValue)=0 then
  1072. Clear
  1073. else
  1074. begin
  1075. Val(AVAlue,L,Code);
  1076. If Code=0 then
  1077. SetAsLargeint(L)
  1078. else
  1079. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  1080. end;
  1081. end;
  1082. procedure TLargeintField.SetVarValue(const AValue: Variant);
  1083. begin
  1084. SetAsLargeint(AValue);
  1085. end;
  1086. Function TLargeintField.CheckRange(AValue : largeint) : Boolean;
  1087. begin
  1088. result := true;
  1089. if (FMaxValue=0) then
  1090. begin
  1091. if (AValue>FMaxRange) Then result := false;
  1092. end
  1093. else
  1094. if AValue>FMaxValue then result := false;
  1095. if (FMinValue=0) then
  1096. begin
  1097. if (AValue<FMinRange) Then result := false;
  1098. end
  1099. else
  1100. if AValue<FMinValue then result := false;
  1101. end;
  1102. Procedure TLargeintField.SetMaxValue (AValue : largeint);
  1103. begin
  1104. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1105. FMaxValue:=AValue
  1106. else
  1107. RangeError(AValue,FMinRange,FMaxRange);
  1108. end;
  1109. Procedure TLargeintField.SetMinValue (AValue : largeint);
  1110. begin
  1111. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  1112. FMinValue:=AValue
  1113. else
  1114. RangeError(AValue,FMinRange,FMaxRange);
  1115. end;
  1116. { TSmallintField }
  1117. function TSmallintField.GetDataSize: Word;
  1118. begin
  1119. Result:=SizeOf(SmallInt);
  1120. end;
  1121. constructor TSmallintField.Create(AOwner: TComponent);
  1122. begin
  1123. inherited Create(AOwner);
  1124. SetDataType(ftSmallInt);
  1125. FMinRange:=-32768;
  1126. FMaxRange:=32767;
  1127. end;
  1128. { TWordField }
  1129. function TWordField.GetDataSize: Word;
  1130. begin
  1131. Result:=SizeOf(Word);
  1132. end;
  1133. constructor TWordField.Create(AOwner: TComponent);
  1134. begin
  1135. inherited Create(AOwner);
  1136. SetDataType(ftWord);
  1137. FMinRange:=0;
  1138. FMaxRange:=65535;
  1139. FValidchars:=['+','0'..'9'];
  1140. end;
  1141. { TAutoIncField }
  1142. constructor TAutoIncField.Create(AOwner: TComponent);
  1143. begin
  1144. Inherited Create(AOWner);
  1145. SetDataType(ftAutoInc);
  1146. FReadOnly:=True;
  1147. end;
  1148. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  1149. begin
  1150. DataBaseError(SCantSetAutoIncfields);
  1151. end;
  1152. { TFloatField }
  1153. function TFloatField.GetAsFloat: Double;
  1154. begin
  1155. If Not GetData(@Result) Then
  1156. Result:=0.0;
  1157. end;
  1158. function TFloatField.GetAsVariant: Variant;
  1159. Var f : Double;
  1160. begin
  1161. If GetData(@f) then
  1162. Result := f
  1163. else
  1164. Result:=Null;
  1165. end;
  1166. function TFloatField.GetAsLongint: Longint;
  1167. begin
  1168. Result:=Round(GetAsFloat);
  1169. end;
  1170. function TFloatField.GetAsString: string;
  1171. Var R : Double;
  1172. begin
  1173. If GetData(@R) then
  1174. Result:=FloatToStr(R)
  1175. else
  1176. Result:='';
  1177. end;
  1178. function TFloatField.GetDataSize: Word;
  1179. begin
  1180. Result:=SizeOf(Double);
  1181. end;
  1182. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  1183. Var
  1184. fmt : string;
  1185. E : Double;
  1186. begin
  1187. TheText:='';
  1188. If Not GetData(@E) then exit;
  1189. If ADisplayText or (Length(FEditFormat) = 0) Then
  1190. Fmt:=FDisplayFormat
  1191. else
  1192. Fmt:=FEditFormat;
  1193. If fmt<>'' then
  1194. TheText:=FormatFloat(fmt,E)
  1195. else
  1196. TheText:=FloatToStrF(E,ffgeneral,FPrecision,0);
  1197. end;
  1198. procedure TFloatField.SetAsFloat(AValue: Double);
  1199. begin
  1200. If CheckRange(AValue) then
  1201. SetData(@Avalue)
  1202. else
  1203. RangeError(AValue,FMinValue,FMaxValue);
  1204. end;
  1205. procedure TFloatField.SetAsLongint(AValue: Longint);
  1206. begin
  1207. SetAsFloat(Avalue);
  1208. end;
  1209. procedure TFloatField.SetAsString(const AValue: string);
  1210. Var R : Double;
  1211. begin
  1212. try
  1213. R := StrToFloat(AValue);
  1214. SetAsFloat(R);
  1215. except
  1216. DatabaseErrorFmt(SNotAFloat, [AValue]);
  1217. end;
  1218. end;
  1219. procedure TFloatField.SetVarValue(const AValue: Variant);
  1220. begin
  1221. SetAsFloat(Avalue);
  1222. end;
  1223. constructor TFloatField.Create(AOwner: TComponent);
  1224. begin
  1225. Inherited Create(AOwner);
  1226. SetDatatype(ftfloat);
  1227. FPrecision:=15;
  1228. FValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
  1229. end;
  1230. Function TFloatField.CheckRange(AValue : Double) : Boolean;
  1231. begin
  1232. If (FMinValue<>0) or (FmaxValue<>0) then
  1233. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  1234. else
  1235. Result:=True;
  1236. end;
  1237. { TCurrencyField }
  1238. Constructor TCurrencyField.Create(AOwner: TComponent);
  1239. begin
  1240. inherited Create(AOwner);
  1241. SetDataType(ftCurrency);
  1242. end;
  1243. procedure TCurrencyField.GetText(var TheText: string; ADisplayText: Boolean);
  1244. Var
  1245. fmt : string;
  1246. ff: TFloatFormat;
  1247. E : Double;
  1248. begin
  1249. TheText:='';
  1250. If Not GetData(@E) then exit;
  1251. If ADisplayText or (Length(FEditFormat) = 0) Then
  1252. Fmt:=FDisplayFormat
  1253. else
  1254. Fmt:=FEditFormat;
  1255. if ADisplayText then
  1256. ff := ffCurrency
  1257. else
  1258. ff := ffFixed;
  1259. If fmt<>'' then
  1260. TheText:=FormatFloat(fmt, E)
  1261. else
  1262. TheText:=FloatToStrF(E, ff, FPrecision, CurrencyDecimals);
  1263. end;
  1264. { TBooleanField }
  1265. function TBooleanField.GetAsBoolean: Boolean;
  1266. var b : wordbool;
  1267. begin
  1268. If GetData(@b) then
  1269. result := b
  1270. else
  1271. Result:=False;
  1272. end;
  1273. function TBooleanField.GetAsVariant: Variant;
  1274. Var b : wordbool;
  1275. begin
  1276. If GetData(@b) then
  1277. Result := b
  1278. else
  1279. Result:=Null;
  1280. end;
  1281. function TBooleanField.GetAsString: string;
  1282. Var B : wordbool;
  1283. begin
  1284. If Getdata(@B) then
  1285. Result:=FDisplays[False,B]
  1286. else
  1287. result:='';
  1288. end;
  1289. function TBooleanField.GetDataSize: Word;
  1290. begin
  1291. Result:=SizeOf(wordBool);
  1292. end;
  1293. function TBooleanField.GetDefaultWidth: Longint;
  1294. begin
  1295. Result:=Length(FDisplays[false,false]);
  1296. If Result<Length(FDisplays[false,True]) then
  1297. Result:=Length(FDisplays[false,True]);
  1298. end;
  1299. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  1300. var b : wordbool;
  1301. begin
  1302. b := AValue;
  1303. SetData(@b);
  1304. end;
  1305. procedure TBooleanField.SetAsString(const AValue: string);
  1306. Var Temp : string;
  1307. begin
  1308. Temp:=UpperCase(AValue);
  1309. if Temp='' then
  1310. Clear
  1311. else if pos(Temp, FDisplays[True,True])=1 then
  1312. SetAsBoolean(True)
  1313. else if pos(Temp, FDisplays[True,False])=1 then
  1314. SetAsBoolean(False)
  1315. else
  1316. DatabaseErrorFmt(SNotABoolean,[AValue]);
  1317. end;
  1318. procedure TBooleanField.SetVarValue(const AValue: Variant);
  1319. begin
  1320. SetAsBoolean(AValue);
  1321. end;
  1322. constructor TBooleanField.Create(AOwner: TComponent);
  1323. begin
  1324. Inherited Create(AOwner);
  1325. SetDataType(ftBoolean);
  1326. DisplayValues:='True;False';
  1327. end;
  1328. Procedure TBooleanField.SetDisplayValues(AValue : String);
  1329. Var I : longint;
  1330. begin
  1331. If FDisplayValues<>AValue then
  1332. begin
  1333. I:=Pos(';',AValue);
  1334. If (I<2) or (I=Length(AValue)) then
  1335. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  1336. FdisplayValues:=AValue;
  1337. // Store display values and their uppercase equivalents;
  1338. FDisplays[False,True]:=Copy(AValue,1,I-1);
  1339. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  1340. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  1341. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  1342. PropertyChanged(True);
  1343. end;
  1344. end;
  1345. { TDateTimeField }
  1346. procedure TDateTimeField.SetDisplayFormat(const AValue: string);
  1347. begin
  1348. if FDisplayFormat<>AValue then begin
  1349. FDisplayFormat:=AValue;
  1350. PropertyChanged(True);
  1351. end;
  1352. end;
  1353. function TDateTimeField.GetAsDateTime: TDateTime;
  1354. begin
  1355. If Not GetData(@Result) then
  1356. Result:=0;
  1357. end;
  1358. procedure TDateTimeField.SetVarValue(const AValue: Variant);
  1359. begin
  1360. SetAsDateTime(AValue);
  1361. end;
  1362. function TDateTimeField.GetAsVariant: Variant;
  1363. Var d : tDateTime;
  1364. begin
  1365. If Getdata(@d) then
  1366. Result := d
  1367. else
  1368. Result:=Null;
  1369. end;
  1370. function TDateTimeField.GetAsFloat: Double;
  1371. begin
  1372. Result:=GetAsdateTime;
  1373. end;
  1374. function TDateTimeField.GetAsString: string;
  1375. begin
  1376. GetText(Result,False);
  1377. end;
  1378. function TDateTimeField.GetDataSize: Word;
  1379. begin
  1380. Result:=SizeOf(TDateTime);
  1381. end;
  1382. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  1383. Var R : TDateTime;
  1384. F : String;
  1385. begin
  1386. If Not Getdata(@R) then
  1387. TheText:=''
  1388. else
  1389. begin
  1390. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  1391. F:=FDisplayFormat
  1392. else
  1393. Case DataType of
  1394. ftTime : F:=ShortTimeFormat;
  1395. ftDate : F:=ShortDateFormat;
  1396. else
  1397. F:='c'
  1398. end;
  1399. TheText:=FormatDateTime(F,R);
  1400. end;
  1401. end;
  1402. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  1403. begin
  1404. SetData(@Avalue);
  1405. end;
  1406. procedure TDateTimeField.SetAsFloat(AValue: Double);
  1407. begin
  1408. SetAsDateTime(AValue);
  1409. end;
  1410. procedure TDateTimeField.SetAsString(const AValue: string);
  1411. Var R : TDateTime;
  1412. begin
  1413. R:=StrToDateTime(AVAlue);
  1414. SetData(@R);
  1415. end;
  1416. constructor TDateTimeField.Create(AOwner: TComponent);
  1417. begin
  1418. Inherited Create(AOwner);
  1419. SetDataType(ftDateTime);
  1420. end;
  1421. { TDateField }
  1422. constructor TDateField.Create(AOwner: TComponent);
  1423. begin
  1424. Inherited Create(AOwner);
  1425. SetDataType(ftDate);
  1426. end;
  1427. { TTimeField }
  1428. constructor TTimeField.Create(AOwner: TComponent);
  1429. begin
  1430. Inherited Create(AOwner);
  1431. SetDataType(ftTime);
  1432. end;
  1433. procedure TTimeField.SetAsString(const AValue: string);
  1434. Var R : TDateTime;
  1435. begin
  1436. R:=StrToTime(AVAlue);
  1437. SetData(@R);
  1438. end;
  1439. { TBinaryField }
  1440. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  1441. begin
  1442. // Just check for really invalid stuff; actual size is
  1443. // dependent on the record...
  1444. If AValue<1 then
  1445. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1446. end;
  1447. function TBinaryField.GetAsString: string;
  1448. begin
  1449. Setlength(Result,DataSize);
  1450. GetData(Pointer(Result));
  1451. end;
  1452. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  1453. begin
  1454. TheText:=GetAsString;
  1455. end;
  1456. procedure TBinaryField.SetAsString(const AValue: string);
  1457. Var Buf : PChar;
  1458. Allocated : Boolean;
  1459. begin
  1460. Allocated:=False;
  1461. If Length(AVAlue)=DataSize then
  1462. Buf:=PChar(Avalue)
  1463. else
  1464. begin
  1465. GetMem(Buf,DataSize);
  1466. Move(Pchar(Avalue)[0],Buf^,DataSize);
  1467. Allocated:=True;
  1468. end;
  1469. SetData(Buf);
  1470. If Allocated then
  1471. FreeMem(Buf,DataSize);
  1472. end;
  1473. procedure TBinaryField.SetText(const AValue: string);
  1474. begin
  1475. SetAsString(Avalue);
  1476. end;
  1477. procedure TBinaryField.SetVarValue(const AValue: Variant);
  1478. begin
  1479. SetAsString(Avalue);
  1480. end;
  1481. constructor TBinaryField.Create(AOwner: TComponent);
  1482. begin
  1483. Inherited Create(AOwner);
  1484. end;
  1485. { TBytesField }
  1486. function TBytesField.GetDataSize: Word;
  1487. begin
  1488. Result:=Size;
  1489. end;
  1490. constructor TBytesField.Create(AOwner: TComponent);
  1491. begin
  1492. Inherited Create(AOwner);
  1493. SetDataType(ftBytes);
  1494. Size:=16;
  1495. end;
  1496. { TVarBytesField }
  1497. function TVarBytesField.GetDataSize: Word;
  1498. begin
  1499. Result:=Size+2;
  1500. end;
  1501. constructor TVarBytesField.Create(AOwner: TComponent);
  1502. begin
  1503. INherited Create(AOwner);
  1504. SetDataType(ftvarbytes);
  1505. Size:=16;
  1506. end;
  1507. { TBCDField }
  1508. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  1509. begin
  1510. If not (AValue in [1..4]) then
  1511. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  1512. end;
  1513. function TBCDField.GetAsCurrency: Currency;
  1514. Var C : system.Currency;
  1515. begin
  1516. if GetData(@C) then
  1517. result := C;
  1518. end;
  1519. function TBCDField.GetAsVariant: Variant;
  1520. Var c : system.Currency;
  1521. begin
  1522. If GetData(@c) then
  1523. Result := c
  1524. else
  1525. Result:=Null;
  1526. end;
  1527. function TBCDField.GetAsFloat: Double;
  1528. begin
  1529. result := GetAsCurrency;
  1530. end;
  1531. function TBCDField.GetAsLongint: Longint;
  1532. begin
  1533. result := round(GetAsCurrency);
  1534. end;
  1535. function TBCDField.GetAsString: string;
  1536. var c : system.currency;
  1537. begin
  1538. If GetData(@C) then
  1539. Result:=CurrToStr(C)
  1540. else
  1541. Result:='';
  1542. end;
  1543. function TBCDField.GetValue(var AValue: Currency): Boolean;
  1544. begin
  1545. Result := GetData(@AValue);
  1546. end;
  1547. function TBCDField.GetDataSize: Word;
  1548. begin
  1549. result := sizeof(currency);
  1550. end;
  1551. function TBCDField.GetDefaultWidth: Longint;
  1552. begin
  1553. if precision > 0 then result := precision
  1554. else result := 10;
  1555. end;
  1556. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  1557. var
  1558. c : system.currency;
  1559. fmt: String;
  1560. begin
  1561. if GetData(@C) then begin
  1562. if aDisplayText or (FEditFormat='') then
  1563. fmt := FDisplayFormat
  1564. else
  1565. fmt := FEditFormat;
  1566. if fmt<>'' then
  1567. TheText := FormatFloat(fmt,C)
  1568. else if fCurrency then begin
  1569. if aDisplayText then
  1570. TheText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?})
  1571. else
  1572. TheText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?});
  1573. end else
  1574. TheText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?});
  1575. end else
  1576. TheText := '';
  1577. end;
  1578. procedure TBCDField.SetAsCurrency(AValue: Currency);
  1579. begin
  1580. If CheckRange(AValue) then
  1581. setdata(@AValue)
  1582. else
  1583. RangeError(AValue,FMinValue,FMaxvalue);
  1584. end;
  1585. procedure TBCDField.SetVarValue(const AValue: Variant);
  1586. begin
  1587. SetAsCurrency(AValue);
  1588. end;
  1589. Function TBCDField.CheckRange(AValue : Currency) : Boolean;
  1590. begin
  1591. If (FMinValue<>0) or (FmaxValue<>0) then
  1592. Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue)
  1593. else
  1594. Result:=True;
  1595. end;
  1596. procedure TBCDField.SetAsFloat(AValue: Double);
  1597. begin
  1598. SetAsCurrency(AValue);
  1599. end;
  1600. procedure TBCDField.SetAsLongint(AValue: Longint);
  1601. begin
  1602. SetAsCurrency(AValue);
  1603. end;
  1604. procedure TBCDField.SetAsString(const AValue: string);
  1605. begin
  1606. SetAsCurrency(strtocurr(AValue));
  1607. end;
  1608. constructor TBCDField.Create(AOwner: TComponent);
  1609. begin
  1610. Inherited Create(AOwner);
  1611. FMaxvalue := 0;
  1612. FMinvalue := 0;
  1613. SetDataType(ftBCD);
  1614. FPrecision := 15;
  1615. Size:=4;
  1616. end;
  1617. { TBlobField }
  1618. procedure TBlobField.AssignTo(Dest: TPersistent);
  1619. begin
  1620. //!! To be implemented
  1621. end;
  1622. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  1623. begin
  1624. Result:=FDataset.CreateBlobStream(Self,Mode);
  1625. end;
  1626. procedure TBlobField.FreeBuffers;
  1627. begin
  1628. end;
  1629. function TBlobField.GetAsString: string;
  1630. var
  1631. Stream: TStream;
  1632. begin
  1633. Stream := GetBlobStream(bmRead);
  1634. if Stream <> nil then
  1635. With Stream do
  1636. try
  1637. SetLength(Result,Size);
  1638. ReadBuffer(Pointer(Result)^,Size);
  1639. finally
  1640. Free
  1641. end
  1642. else
  1643. Result := '(blob)';
  1644. end;
  1645. function TBlobField.GetBlobSize: Longint;
  1646. var
  1647. Stream: TStream;
  1648. begin
  1649. Stream := GetBlobStream(bmread);
  1650. if Stream <> nil then
  1651. With Stream do
  1652. try
  1653. Result:=Size;
  1654. finally
  1655. Free;
  1656. end
  1657. else
  1658. result := 0;
  1659. end;
  1660. function TBlobField.GetIsNull: Boolean;
  1661. begin
  1662. If Not Modified then
  1663. result:= inherited GetIsnull
  1664. else
  1665. With GetBlobStream(bmread) do
  1666. try
  1667. Result:=(Size=0);
  1668. Finally
  1669. Free;
  1670. end;
  1671. end;
  1672. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  1673. begin
  1674. TheText:=GetAsString;
  1675. end;
  1676. procedure TBlobField.SetAsString(const AValue: string);
  1677. begin
  1678. With GetBlobStream(bmwrite) do
  1679. try
  1680. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1681. finally
  1682. Free;
  1683. end;
  1684. end;
  1685. procedure TBlobField.SetText(const AValue: string);
  1686. begin
  1687. SetAsString(AValue);
  1688. end;
  1689. procedure TBlobField.SetVarValue(const AValue: Variant);
  1690. begin
  1691. SetAsString(AValue);
  1692. end;
  1693. constructor TBlobField.Create(AOwner: TComponent);
  1694. begin
  1695. Inherited Create(AOWner);
  1696. SetDataType(ftBlob);
  1697. end;
  1698. procedure TBlobField.Assign(Source: TPersistent);
  1699. begin
  1700. //!! To be implemented
  1701. end;
  1702. procedure TBlobField.Clear;
  1703. begin
  1704. GetBlobStream(bmWrite).free;
  1705. end;
  1706. class function TBlobField.IsBlob: Boolean;
  1707. begin
  1708. Result:=True;
  1709. end;
  1710. procedure TBlobField.LoadFromFile(const FileName: string);
  1711. Var S : TFileStream;
  1712. begin
  1713. S:=TFileStream.Create(FileName,fmOpenRead);
  1714. try
  1715. LoadFromStream(S);
  1716. finally
  1717. S.Free;
  1718. end;
  1719. end;
  1720. procedure TBlobField.LoadFromStream(Stream: TStream);
  1721. begin
  1722. With GetBlobStream(bmWrite) do
  1723. Try
  1724. CopyFrom(Stream,0);
  1725. finally
  1726. Free;
  1727. end;
  1728. end;
  1729. procedure TBlobField.SaveToFile(const FileName: string);
  1730. Var S : TFileStream;
  1731. begin
  1732. S:=TFileStream.Create(FileName,fmCreate);
  1733. try
  1734. SaveToStream(S);
  1735. finally
  1736. S.Free;
  1737. end;
  1738. end;
  1739. procedure TBlobField.SaveToStream(Stream: TStream);
  1740. Var S : TStream;
  1741. begin
  1742. S:=GetBlobStream(bmRead);
  1743. Try
  1744. Stream.CopyFrom(S,0);
  1745. finally
  1746. S.Free;
  1747. end;
  1748. end;
  1749. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1750. begin
  1751. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1752. SetDatatype(Avalue);
  1753. end;
  1754. { TMemoField }
  1755. constructor TMemoField.Create(AOwner: TComponent);
  1756. begin
  1757. Inherited Create(AOwner);
  1758. SetDataType(ftMemo);
  1759. end;
  1760. { TGraphicField }
  1761. constructor TGraphicField.Create(AOwner: TComponent);
  1762. begin
  1763. Inherited Create(AOwner);
  1764. SetDataType(ftGraphic);
  1765. end;
  1766. { TFields }
  1767. Constructor TFields.Create(ADataset : TDataset);
  1768. begin
  1769. FDataSet:=ADataset;
  1770. FFieldList:=TList.Create;
  1771. FValidFieldKinds:=[fkData..fkInternalcalc];
  1772. end;
  1773. Destructor TFields.Destroy;
  1774. begin
  1775. if FFieldList <> nil then Clear;
  1776. FFieldList.Free;
  1777. inherited Destroy;
  1778. end;
  1779. Procedure Tfields.Changed;
  1780. begin
  1781. if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) then
  1782. FDataSet.DataEvent(deFieldListChange, 0);
  1783. If Assigned(FOnChange) then
  1784. FOnChange(Self);
  1785. end;
  1786. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1787. begin
  1788. If Not (FieldKind in ValidFieldKinds) Then
  1789. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1790. end;
  1791. Function Tfields.GetCount : Longint;
  1792. begin
  1793. Result:=FFieldList.Count;
  1794. end;
  1795. Function TFields.GetField (Index : longint) : TField;
  1796. begin
  1797. Result:=Tfield(FFieldList[Index]);
  1798. end;
  1799. procedure Tfields.SetField(Index: Integer; Value: TField);
  1800. begin
  1801. Fields[Index].Assign(Value);
  1802. end;
  1803. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1804. Var Old : Longint;
  1805. begin
  1806. Old := FFieldList.indexOf(Field);
  1807. If Old=-1 then
  1808. Exit;
  1809. // Check value
  1810. If Value<0 Then Value:=0;
  1811. If Value>=Count then Value:=Count-1;
  1812. If Value<>Old then
  1813. begin
  1814. FFieldList.Delete(Old);
  1815. FFieldList.Insert(Value,Field);
  1816. Field.PropertyChanged(True);
  1817. Changed;
  1818. end;
  1819. end;
  1820. Procedure TFields.Add(Field : TField);
  1821. begin
  1822. CheckFieldName(Field.FieldName);
  1823. FFieldList.Add(Field);
  1824. Field.FFields:=Self;
  1825. Changed;
  1826. end;
  1827. Procedure TFields.CheckFieldName (Const Value : String);
  1828. begin
  1829. If FindField(Value)<>Nil then
  1830. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1831. end;
  1832. Procedure TFields.CheckFieldNames (Const Value : String);
  1833. Var I : longint;
  1834. S,T : String;
  1835. begin
  1836. T:=Value;
  1837. Repeat
  1838. I:=Pos(T,';');
  1839. If I=0 Then I:=Length(T)+1;
  1840. S:=Copy(T,1,I-1);
  1841. Delete(T,1,I);
  1842. // Will raise an error if no such field...
  1843. FieldByName(S);
  1844. Until (T='');
  1845. end;
  1846. Procedure TFields.Clear;
  1847. begin
  1848. with FFieldList do
  1849. while Count > 0 do begin
  1850. TField(Last).FDataSet := Nil;
  1851. TField(Last).Free;
  1852. FFieldList.Delete(Count - 1);
  1853. end;
  1854. Changed;
  1855. end;
  1856. Function TFields.FindField (Const Value : String) : TField;
  1857. Var S : String;
  1858. I : longint;
  1859. begin
  1860. Result:=Nil;
  1861. S:=UpperCase(Value);
  1862. For I:=0 To FFieldList.Count-1 do
  1863. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1864. Begin
  1865. {$ifdef dsdebug}
  1866. Writeln ('Found field ',Value);
  1867. {$endif}
  1868. Result:=TField(FFieldList[I]);
  1869. Exit;
  1870. end;
  1871. end;
  1872. Function TFields.FieldByName (Const Value : String) : TField;
  1873. begin
  1874. Result:=FindField(Value);
  1875. If result=Nil then
  1876. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1877. end;
  1878. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1879. Var i : Longint;
  1880. begin
  1881. Result:=Nil;
  1882. For I:=0 to FFieldList.Count-1 do
  1883. If FieldNo=TField(FFieldList[I]).FieldNo then
  1884. begin
  1885. Result:=TField(FFieldList[i]);
  1886. Exit;
  1887. end;
  1888. end;
  1889. Procedure TFields.GetFieldNames (Values : TStrings);
  1890. Var i : longint;
  1891. begin
  1892. Values.Clear;
  1893. For I:=0 to FFieldList.Count-1 do
  1894. Values.Add(Tfield(FFieldList[I]).FieldName);
  1895. end;
  1896. Function TFields.IndexOf(Field : TField) : Longint;
  1897. begin
  1898. Result:=FFieldList.IndexOf(Field);
  1899. end;
  1900. procedure TFields.Remove(Value : TField);
  1901. begin
  1902. FFieldList.Remove(Value);
  1903. Value.FFields := nil;
  1904. Changed;
  1905. end;