fields.inc 45 KB

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