fields.inc 45 KB

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