fields.inc 43 KB

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