fields.inc 46 KB

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