fields.inc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  5. Free Pascal development team
  6. TFields and related components implementations.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. PRocedure DumpMem (P : Pointer;Size : Longint);
  14. Type PByte = ^Byte;
  15. Var i : longint;
  16. begin
  17. Write ('Memory dump : ');
  18. For I:=0 to Size-1 do
  19. Write (Pbyte(P)[i],' ');
  20. Writeln;
  21. end;
  22. { ---------------------------------------------------------------------
  23. TFieldDef
  24. ---------------------------------------------------------------------}
  25. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  26. ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Longint);
  27. begin
  28. Inherited Create(AOwner);
  29. {$ifdef dsdebug }
  30. Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')');
  31. {$endif}
  32. FName:=Aname;
  33. FDatatype:=ADatatype;
  34. FSize:=ASize;
  35. FRequired:=ARequired;
  36. FPrecision:=-1;
  37. // Correct sizes.
  38. If FDataType=ftFloat then
  39. begin
  40. If Not (FSize in [4,8,10]) then FSize:=10
  41. end
  42. else If FDataType in [ftWord,ftsmallint,ftinteger] Then
  43. If Not (FSize in [1,2,4]) then FSize:=4;
  44. FFieldNo:=AFieldNo;
  45. AOwner.FItems.Add(Self);
  46. end;
  47. Destructor TFieldDef.Destroy;
  48. Var I : longint;
  49. begin
  50. Inherited destroy;
  51. end;
  52. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  53. Var TheField : TFieldClass;
  54. begin
  55. {$ifdef dsdebug}
  56. Writeln ('Creating field '+FNAME);
  57. {$endif dsdebug}
  58. TheField:=GetFieldClass;
  59. if TheField=Nil then
  60. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  61. Result:=Thefield.Create(AOwner);
  62. Try
  63. Result.Size:=FSize;
  64. Result.Required:=FRequired;
  65. Result.FieldName:=FName;
  66. Result.FFieldNo:=Self.FieldNo;
  67. Result.SetFieldType(DataType);
  68. {$ifdef dsdebug}
  69. Writeln ('TFieldDef.CReateField : Trying to set dataset');
  70. {$endif dsdebug}
  71. {$ifdef dsdebug}
  72. Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo);
  73. {$endif dsdebug}
  74. Result.Dataset:=TFieldDefs(Owner).FDataset;
  75. If Result is TFloatField then
  76. TFloatField(Result).Precision:=FPrecision;
  77. except
  78. Result.Free;
  79. Raise;
  80. end;
  81. end;
  82. Function TFieldDef.GetFieldClass : TFieldClass;
  83. begin
  84. //!! Should be owner as tdataset but that doesn't work ??
  85. If Assigned(Owner) then
  86. Result:=TFieldDefs(Owner).FDataSet.GetFieldClass(FDataType)
  87. else
  88. Result:=Nil;
  89. end;
  90. { ---------------------------------------------------------------------
  91. TFieldDefs
  92. ---------------------------------------------------------------------}
  93. destructor TFieldDefs.Destroy;
  94. begin
  95. FItems.Free;
  96. // This will destroy all fielddefs since we own them...
  97. Inherited Destroy;
  98. end;
  99. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  100. ARequired: Boolean);
  101. begin
  102. If Length(AName)=0 Then
  103. DatabaseError(SNeedFieldName);
  104. // the fielddef will register itself here as a owned component.
  105. // fieldno is 1 based !
  106. TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,FItems.Count+1);
  107. end;
  108. function TFieldDefs.GetCount: Longint;
  109. begin
  110. Result:=FItems.Count;
  111. end;
  112. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  113. begin
  114. Result:=TFieldDef(FItems[Index]);
  115. end;
  116. constructor TFieldDefs.Create(ADataSet: TDataSet);
  117. begin
  118. Inherited Create(ADataSet);
  119. FItems:=TList.Create;
  120. FDataset:=ADataset;
  121. end;
  122. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  123. Var I : longint;
  124. begin
  125. Clear;
  126. For i:=1 to FieldDefs.Count-1 do
  127. With FieldDefs[i] do
  128. Add(Name,DataType,Size,Required);
  129. end;
  130. procedure TFieldDefs.Clear;
  131. Var I : longint;
  132. begin
  133. For I:=FItems.Count-1 downto 0 do
  134. TFieldDef(Fitems[i]).Free;
  135. FItems.Clear;
  136. end;
  137. function TFieldDefs.Find(const AName: string): TFieldDef;
  138. Var I : longint;
  139. begin
  140. I:=IndexOf(AName);
  141. If I=-1 Then
  142. DataBaseErrorFmt(SUnknownField,[AName,FDataSet.Name]);
  143. Result:=TFieldDef(Fitems[i]);
  144. end;
  145. function TFieldDefs.IndexOf(const AName: string): Longint;
  146. Var I : longint;
  147. begin
  148. For I:=0 to Fitems.Count-1 do
  149. If AnsiCompareText(TFieldDef(FItems[I]).Name,AName)=0 then
  150. begin
  151. Result:=I;
  152. Exit;
  153. end;
  154. Result:=-1;
  155. end;
  156. procedure TFieldDefs.Update;
  157. begin
  158. FDataSet.UpdateFieldDefs;
  159. end;
  160. { ---------------------------------------------------------------------
  161. TField
  162. ---------------------------------------------------------------------}
  163. Const
  164. SBoolean = 'Boolean';
  165. SDateTime = 'TDateTime';
  166. SFloat = 'Float';
  167. SInteger = 'Integer';
  168. SString = 'String';
  169. constructor TField.Create(AOwner: TComponent);
  170. begin
  171. Inherited Create(AOwner);
  172. FVisible:=True;
  173. FValidChars:=[#0..#155];
  174. end;
  175. destructor TField.Destroy;
  176. begin
  177. IF Assigned(FDataSet) then
  178. begin
  179. FDataSet.Active:=False;
  180. FDataSet.RemoveField(Self);
  181. end;
  182. Inherited Destroy;
  183. end;
  184. function TField.AccessError(const TypeName: string): EDatabaseError;
  185. begin
  186. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  187. end;
  188. procedure TField.Assign(Source: TPersistent);
  189. begin
  190. //!! To be implemented
  191. end;
  192. procedure TField.Change;
  193. begin
  194. If Assigned(FOnChange) Then
  195. FOnChange(Self);
  196. end;
  197. procedure TField.CheckInactive;
  198. begin
  199. If Assigned(FDataSet) then
  200. FDataset.CheckInactive;
  201. end;
  202. procedure TField.Clear;
  203. begin
  204. SetData(Nil);
  205. end;
  206. procedure TField.DataChanged;
  207. begin
  208. FDataset.DataEvent(deFieldChange,longint(Self));
  209. end;
  210. procedure TField.FocusControl;
  211. begin
  212. FDataSet.DataEvent(deFocusControl,longint(Self));
  213. end;
  214. procedure TField.FreeBuffers;
  215. begin
  216. // Empty. Provided for backward compatibiliy;
  217. // TDataset manages the buffers.
  218. end;
  219. function TField.GetAsBoolean: Boolean;
  220. begin
  221. AccessError(SBoolean);
  222. end;
  223. function TField.GetAsDateTime: TDateTime;
  224. begin
  225. AccessError(SdateTime);
  226. end;
  227. function TField.GetAsFloat: Extended;
  228. begin
  229. AccessError(SDateTime);
  230. end;
  231. function TField.GetAsLongint: Longint;
  232. begin
  233. AccessError(SInteger);
  234. end;
  235. function TField.GetAsString: string;
  236. begin
  237. AccessError(SString);
  238. end;
  239. function TField.GetCanModify: Boolean;
  240. begin
  241. Result:=Not ReadOnly;
  242. If Result then
  243. begin
  244. Result:=Assigned(DataSet);
  245. If Result then
  246. Result:= DataSet.CanModify;
  247. end;
  248. end;
  249. function TField.GetData(Buffer: Pointer): Boolean;
  250. begin
  251. IF FDataset=Nil then
  252. DatabaseErrorFmt(SNoDataset,[FieldName]);
  253. If FVAlidating then
  254. begin
  255. result:=Not(FValueBuffer=Nil);
  256. If Result then
  257. Move (FValueBuffer^,Buffer^ ,DataSize);
  258. end
  259. else
  260. Result:=FDataset.GetFieldData(Self,Buffer);
  261. end;
  262. function TField.GetDataSize: Word;
  263. begin
  264. Result:=0;
  265. end;
  266. function TField.GetDefaultWidth: Longint;
  267. begin
  268. Result:=10;
  269. end;
  270. function TField.GetDisplayName : String;
  271. begin
  272. If FDisplayLabel<>'' then
  273. result:=FDisplayLabel
  274. else
  275. Result:=FFieldName;
  276. end;
  277. function TField.getIndex : longint;
  278. begin
  279. If Assigned(FDataset) then
  280. Result:=FDataset.FFieldList.IndexOf(Self)
  281. else
  282. Result:=-1;
  283. end;
  284. function TField.GetIsNull: Boolean;
  285. begin
  286. Result:=Not(GetData (Nil));
  287. end;
  288. function TField.GetParentComponent: TComponent;
  289. begin
  290. //!! To be implemented
  291. end;
  292. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  293. begin
  294. AText:=GetAsString;
  295. end;
  296. function TField.HasParent: Boolean;
  297. begin
  298. HasParent:=True;
  299. end;
  300. function TField.IsValidChar(InputChar: Char): Boolean;
  301. begin
  302. // FValidChars must be set in Create.
  303. Result:=InputChar in FValidChars;
  304. end;
  305. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  306. begin
  307. Inherited Notification(AComponent,Operation);
  308. end;
  309. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  310. begin
  311. If (FDataset<>Nil) and (FDataset.Active) then
  312. If LayoutAffected then
  313. FDataset.DataEvent(deLayoutChange,0)
  314. else
  315. FDataset.DataEvent(deDatasetchange,0);
  316. end;
  317. procedure TField.ReadState(Reader: TReader);
  318. begin
  319. //!! To be implemented
  320. end;
  321. procedure TField.SetAsBoolean(AValue: Boolean);
  322. begin
  323. AccessError(SBoolean);
  324. end;
  325. procedure TField.SetAsDateTime(AValue: TDateTime);
  326. begin
  327. AccessError(SDateTime);
  328. end;
  329. procedure TField.SetAsFloat(AValue: Extended);
  330. begin
  331. AccessError(SFloat);
  332. end;
  333. procedure TField.SetAsLongint(AValue: Longint);
  334. begin
  335. AccessError(SInteger);
  336. end;
  337. procedure TField.SetAsString(const AValue: string);
  338. begin
  339. AccessError(SString);
  340. end;
  341. procedure TField.SetData(Buffer: Pointer);
  342. begin
  343. If Not Assigned(FDataset) then
  344. EDatabaseError.CreateFmt(SNoDataset,[FieldName]);
  345. FDataSet.SetFieldData(Self,Buffer);
  346. end;
  347. Procedure TField.SetDataset (Value : TDataset);
  348. begin
  349. {$ifdef dsdebug}
  350. Writeln ('Setting dataset');
  351. {$endif}
  352. If Value=FDataset then exit;
  353. If Assigned(FDataset) Then FDataset.CheckInactive;
  354. If Assigned(Value) then
  355. begin
  356. Value.CheckInactive;
  357. // ?? Identifier idents no member ??
  358. Value.FFieldList.CheckFieldName(FFieldName);
  359. end;
  360. If Assigned(FDataset) then
  361. FDataset.FFieldList.Remove(Self);
  362. If Assigned(Value) then
  363. Value.FFieldList.Add(Self);
  364. FDataset:=Value;
  365. end;
  366. procedure TField.SetDataType(AValue: TFieldType);
  367. begin
  368. FDataType := AValue;
  369. end;
  370. procedure TField.SetFieldType(AValue: TFieldType);
  371. begin
  372. //!! To be implemented
  373. end;
  374. procedure TField.SetParentComponent(AParent: TComponent);
  375. begin
  376. //!! To be implemented
  377. end;
  378. procedure TField.SetSize(AValue: Word);
  379. begin
  380. CheckInactive;
  381. CheckTypeSize(AValue);
  382. FSize:=AValue;
  383. end;
  384. procedure TField.SetText(const AValue: string);
  385. begin
  386. AsString:=AValue;
  387. end;
  388. procedure TField.Validate(Buffer: Pointer);
  389. begin
  390. If assigned(OnValidate) Then
  391. begin
  392. FValueBuffer:=Buffer;
  393. FValidating:=True;
  394. Try
  395. OnValidate(Self);
  396. finally
  397. FValidating:=False;
  398. end;
  399. end;
  400. end;
  401. class function Tfield.IsBlob: Boolean;
  402. begin
  403. Result:=False;
  404. end;
  405. class procedure TField.CheckTypeSize(AValue: Longint);
  406. begin
  407. If (AValue<>0) and Not IsBlob Then
  408. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  409. end;
  410. // TField private methods
  411. function TField.GetDisplayText: String;
  412. begin
  413. SetLength(Result, 0);
  414. if Assigned(OnGetText) then
  415. OnGetText(Self, Result, True)
  416. else
  417. GetText(Result, True);
  418. end;
  419. { ---------------------------------------------------------------------
  420. TStringField
  421. ---------------------------------------------------------------------}
  422. constructor TStringField.Create(AOwner: TComponent);
  423. begin
  424. Inherited Create(AOwner);
  425. SetDataType(ftString);
  426. Size:=20;
  427. end;
  428. class procedure TStringField.CheckTypeSize(AValue: Longint);
  429. begin
  430. If (AValue<1) or (AValue>dsMaxStringSize) Then
  431. databaseErrorFmt(SInvalidFieldSize,[AValue])
  432. end;
  433. function TStringField.GetAsBoolean: Boolean;
  434. Var S : String;
  435. begin
  436. S:=GetAsString;
  437. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  438. end;
  439. function TStringField.GetAsDateTime: TDateTime;
  440. begin
  441. Result:=StrToDateTime(GetAsString);
  442. end;
  443. function TStringField.GetAsFloat: Extended;
  444. begin
  445. Result:=StrToFloat(GetAsString);
  446. end;
  447. function TStringField.GetAsLongint: Longint;
  448. begin
  449. Result:=StrToInt(GetAsString);
  450. end;
  451. function TStringField.GetAsString: string;
  452. begin
  453. If Not GetValue(Result) then
  454. Result:='';
  455. end;
  456. function TStringField.GetDataSize: Word;
  457. begin
  458. Result:=Size+1;
  459. end;
  460. function TStringField.GetDefaultWidth: Longint;
  461. begin
  462. result:=Size;
  463. end;
  464. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  465. begin
  466. AText:=GetAsString;
  467. end;
  468. function TStringField.GetValue(var AValue: string): Boolean;
  469. Var Buf : TStringFieldBuffer;
  470. begin
  471. Result:=GetData(@Buf);
  472. If Result then
  473. AValue:=Buf;
  474. end;
  475. procedure TStringField.SetAsBoolean(AValue: Boolean);
  476. begin
  477. If AValue Then
  478. SetAsString('T')
  479. else
  480. SetAsString('F');
  481. end;
  482. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  483. begin
  484. SetAsString(DateTimeToStr(AValue));
  485. end;
  486. procedure TStringField.SetAsFloat(AValue: Extended);
  487. begin
  488. SetAsString(FloatToStr(AValue));
  489. end;
  490. procedure TStringField.SetAsLongint(AValue: Longint);
  491. begin
  492. SetAsString(intToStr(AValue));
  493. end;
  494. procedure TStringField.SetAsString(const AValue: string);
  495. Const NullByte : char = #0;
  496. begin
  497. IF Length(AValue)=0 then
  498. SetData(@NullByte)
  499. else
  500. SetData(@AValue[1]);
  501. end;
  502. { ---------------------------------------------------------------------
  503. TNumericField
  504. ---------------------------------------------------------------------}
  505. constructor TNumericField.Create(AOwner: TComponent);
  506. begin
  507. Inherited Create(AOwner);
  508. AlignMent:=taRightJustify;
  509. end;
  510. procedure TNumericField.RangeError(AValue, Min, Max: Extended);
  511. begin
  512. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  513. end;
  514. procedure TNumericField.SetDisplayFormat(const AValue: string);
  515. begin
  516. If FDisplayFormat<>AValue then
  517. begin
  518. FDisplayFormat:=AValue;
  519. PropertyChanged(True);
  520. end;
  521. end;
  522. procedure TNumericField.SetEditFormat(const AValue: string);
  523. begin
  524. If FEDitFormat<>AValue then
  525. begin
  526. FEDitFormat:=AVAlue;
  527. PropertyChanged(True);
  528. end;
  529. end;
  530. { ---------------------------------------------------------------------
  531. TLongintField
  532. ---------------------------------------------------------------------}
  533. constructor TLongintField.Create(AOwner: TComponent);
  534. begin
  535. Inherited Create(AOwner);
  536. SetDatatype(ftinteger);
  537. FMinRange:=Low(LongInt);
  538. FMaxRange:=High(LongInt);
  539. FValidchars:=['+','-','0'..'9'];
  540. end;
  541. function TLongintField.GetAsFloat: Extended;
  542. begin
  543. Result:=GetAsLongint;
  544. end;
  545. function TLongintField.GetAsLongint: Longint;
  546. begin
  547. If Not GetValue(Result) then
  548. Result:=0;
  549. end;
  550. function TLongintField.GetAsString: string;
  551. Var L : Longint;
  552. begin
  553. If GetValue(L) then
  554. Result:=IntTostr(L)
  555. else
  556. Result:='';
  557. end;
  558. function TLongintField.GetDataSize: Word;
  559. begin
  560. Result:=SizeOf(Longint);
  561. end;
  562. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  563. var l : longint;
  564. fmt : string;
  565. begin
  566. Atext:='';
  567. If Not GetData(@l) then exit;
  568. If ADisplayText or (FEditFormat='') then
  569. fmt:=FDisplayFormat
  570. else
  571. fmt:=FEditFormat;
  572. { // no formatFloat yet
  573. If length(fmt)<>0 then
  574. AText:=FormatFloat(fmt,L)
  575. else
  576. }
  577. Str(L,AText);
  578. end;
  579. function TLongintField.GetValue(var AValue: Longint): Boolean;
  580. Type
  581. PSmallint = ^SmallInt;
  582. PLongint = ^Longint;
  583. PWord = ^Word;
  584. Var L : Longint;
  585. P : PLongint;
  586. begin
  587. P:=@L;
  588. Result:=GetData(P);
  589. If Result then
  590. Case Datatype of
  591. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  592. ftword : Avalue:=Pword(P)^;
  593. ftsmallint : AValue:=PSmallint(P)^;
  594. end;
  595. end;
  596. procedure TLongintField.SetAsFloat(AValue: Extended);
  597. begin
  598. SetAsLongint(Round(Avalue));
  599. end;
  600. procedure TLongintField.SetAsLongint(AValue: Longint);
  601. begin
  602. If CheckRange(AValue) then
  603. SetData(@AValue)
  604. else
  605. RangeError(Avalue,FMinrange,FMaxRange);
  606. end;
  607. procedure TLongintField.SetAsString(const AValue: string);
  608. Var L,Code : longint;
  609. begin
  610. If length(AValue)=0 then
  611. Clear
  612. else
  613. begin
  614. Val(AVAlue,L,Code);
  615. If Code=0 then
  616. SetAsLongint(L)
  617. else
  618. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  619. end;
  620. end;
  621. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  622. begin
  623. if FMaxValue=0 Then
  624. Result:=(AValue<=FMaxRange) and (AValue>=FMinRange)
  625. else
  626. Result:=(AValue<=FMaxValue) and (AValue>=FMinValue);
  627. end;
  628. Procedure TLongintField.SetMaxValue (AValue : longint);
  629. begin
  630. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  631. FMaxValue:=AValue
  632. else
  633. RangeError(AValue,FMinRange,FMaxRange);
  634. end;
  635. Procedure TLongintField.SetMinValue (AValue : longint);
  636. begin
  637. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  638. FMinValue:=AValue
  639. else
  640. RangeError(AValue,FMinRange,FMaxRange);
  641. end;
  642. { TSmallintField }
  643. function TSmallintField.GetDataSize: Word;
  644. begin
  645. Result:=SizeOf(SmallInt);
  646. end;
  647. constructor TSmallintField.Create(AOwner: TComponent);
  648. begin
  649. inherited Create(AOwner);
  650. SetDataType(ftSmallInt);
  651. FMinRange:=-32768;
  652. FMaxRange:=32767;
  653. end;
  654. { TWordField }
  655. function TWordField.GetDataSize: Word;
  656. begin
  657. Result:=SizeOf(Word);
  658. end;
  659. constructor TWordField.Create(AOwner: TComponent);
  660. begin
  661. inherited Create(AOwner);
  662. SetDataType(ftWord);
  663. FMinRange:=0;
  664. FMaxRange:=65535;
  665. FValidchars:=['+','0'..'9'];
  666. end;
  667. { TAutoIncField }
  668. constructor TAutoIncField.Create(AOwner: TComponent);
  669. begin
  670. Inherited Create(AOWner);
  671. SetDataType(ftAutoInc);
  672. end;
  673. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  674. begin
  675. DataBaseError(SCantSetAutoIncfields);
  676. end;
  677. { TFloatField }
  678. function TFloatField.GetAsFloat: Extended;
  679. begin
  680. If Not GetData(@Result) Then
  681. Result:=0.0;
  682. end;
  683. function TFloatField.GetAsLongint: Longint;
  684. begin
  685. Result:=Round(GetAsFloat);
  686. end;
  687. function TFloatField.GetAsString: string;
  688. Var R : Extended;
  689. begin
  690. If GetData(@R) then
  691. Result:=FloatToStr(R)
  692. else
  693. Result:='';
  694. end;
  695. function TFloatField.GetDataSize: Word;
  696. begin
  697. Result:=SizeOf(Extended);
  698. end;
  699. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  700. Var
  701. fmt : string;
  702. E : Extended;
  703. begin
  704. text:='';
  705. If Not GetData(@E) then exit;
  706. If ADisplayText or (Length(FEditFormat) = 0) Then
  707. Fmt:=FDisplayFormat
  708. else
  709. Fmt:=FEditFormat;
  710. { // No formatfloat yet
  711. If fmt<>'' then
  712. TheText:=FormatFloat(fmt,E)
  713. else
  714. }
  715. Text:=FloatToStrF(E,ffgeneral,FPrecision,0);
  716. end;
  717. procedure TFloatField.SetAsFloat(AValue: Extended);
  718. begin
  719. If CheckRange(AValue) then
  720. SetData(@Avalue)
  721. else
  722. RangeError(AValue,FMinValue,FMaxValue);
  723. end;
  724. procedure TFloatField.SetAsLongint(AValue: Longint);
  725. begin
  726. SetAsFloat(Avalue);
  727. end;
  728. procedure TFloatField.SetAsString(const AValue: string);
  729. Var R : Extended;
  730. Code : longint;
  731. begin
  732. Val(AVAlue,R,Code);
  733. If Code<>0 then
  734. DatabaseErrorFmt(SNotAFloat,[AVAlue])
  735. Else
  736. SetAsFloat(R);
  737. end;
  738. constructor TFloatField.Create(AOwner: TComponent);
  739. begin
  740. Inherited Create(AOwner);
  741. SetDatatype(ftfloat);
  742. end;
  743. Function TFloatField.CheckRange(AValue : Extended) : Boolean;
  744. begin
  745. If (FMinValue<>0) or (FmaxValue<>0) then
  746. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  747. else
  748. Result:=True;
  749. end;
  750. { TBooleanField }
  751. function TBooleanField.GetAsBoolean: Boolean;
  752. begin
  753. If not GetData(@Result) then
  754. Result:=False;
  755. end;
  756. function TBooleanField.GetAsString: string;
  757. Var B : boolean;
  758. begin
  759. If Getdata(@B) then
  760. Result:=FDisplays[False,B]
  761. else
  762. result:='';
  763. end;
  764. function TBooleanField.GetDataSize: Word;
  765. begin
  766. Result:=SizeOf(Boolean);
  767. end;
  768. function TBooleanField.GetDefaultWidth: Longint;
  769. begin
  770. Result:=Length(FDisplays[false,false]);
  771. If Result<Length(FDisplays[false,True]) then
  772. Result:=Length(FDisplays[false,True]);
  773. end;
  774. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  775. begin
  776. SetData(@AValue);
  777. end;
  778. procedure TBooleanField.SetAsString(const AValue: string);
  779. Var Temp : string;
  780. begin
  781. Temp:=UpperCase(AValue);
  782. If Temp=FDisplays[True,True] Then
  783. SetAsBoolean(True)
  784. else If Temp=FDisplays[True,False] then
  785. SetAsBoolean(False)
  786. else
  787. DatabaseErrorFmt(SNotABoolean,[AValue]);
  788. end;
  789. constructor TBooleanField.Create(AOwner: TComponent);
  790. begin
  791. Inherited Create(AOwner);
  792. SetDataType(ftBoolean);
  793. DisplayValues:='True;False';
  794. end;
  795. Procedure TBooleanField.SetDisplayValues(AValue : String);
  796. Var I : longint;
  797. begin
  798. If FDisplayValues<>AValue then
  799. begin
  800. I:=Pos(';',AValue);
  801. If (I<2) or (I=Length(AValue)) then
  802. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  803. FdisplayValues:=AValue;
  804. // Store display values and their uppercase equivalents;
  805. FDisplays[False,True]:=Copy(AValue,1,I-1);
  806. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  807. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  808. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  809. PropertyChanged(True);
  810. end;
  811. end;
  812. { TDateTimeField }
  813. function TDateTimeField.GetAsDateTime: TDateTime;
  814. begin
  815. If Not GetData(@Result) then
  816. Result:=0;
  817. end;
  818. function TDateTimeField.GetAsFloat: Extended;
  819. begin
  820. Result:=GetAsdateTime;
  821. end;
  822. function TDateTimeField.GetAsString: string;
  823. begin
  824. GetText(Result,False);
  825. end;
  826. function TDateTimeField.GetDataSize: Word;
  827. begin
  828. Result:=SizeOf(TDateTime);
  829. end;
  830. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  831. Var R : TDateTime;
  832. F : String;
  833. begin
  834. If Not Getdata(@R) then
  835. TheText:=''
  836. else
  837. begin
  838. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  839. F:=FDisplayFormat
  840. else
  841. Case DataType of
  842. ftTime : F:=ShortTimeFormat;
  843. ftDate : F:=ShortDateFormat;
  844. else
  845. F:='c'
  846. end;
  847. TheText:=FormatDateTime(F,R);
  848. end;
  849. end;
  850. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  851. begin
  852. SetData(@Avalue);
  853. end;
  854. procedure TDateTimeField.SetAsFloat(AValue: Extended);
  855. begin
  856. SetAsDateTime(AValue);
  857. end;
  858. procedure TDateTimeField.SetAsString(const AValue: string);
  859. Var R : TDateTime;
  860. begin
  861. R:=StrToDateTime(AVAlue);
  862. SetData(@R);
  863. end;
  864. constructor TDateTimeField.Create(AOwner: TComponent);
  865. begin
  866. Inherited Create(AOwner);
  867. SetDataType(ftDateTime);
  868. end;
  869. { TDateField }
  870. function TDateField.GetDataSize: Word;
  871. begin
  872. Result:=SizeOf(TDateTime);
  873. end;
  874. constructor TDateField.Create(AOwner: TComponent);
  875. begin
  876. Inherited Create(AOwner);
  877. SetDataType(ftDate);
  878. end;
  879. { TTimeField }
  880. function TTimeField.GetDataSize: Word;
  881. begin
  882. Result:=SizeOf(TDateTime);
  883. end;
  884. constructor TTimeField.Create(AOwner: TComponent);
  885. begin
  886. Inherited Create(AOwner);
  887. SetDataType(ftTime);
  888. end;
  889. { TBinaryField }
  890. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  891. begin
  892. // Just check for really invalid stuff; actual size is
  893. // dependent on the record...
  894. If AValue<1 then
  895. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  896. end;
  897. function TBinaryField.GetAsString: string;
  898. begin
  899. Setlength(Result,DataSize);
  900. GetData(Pointer(Result));
  901. end;
  902. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  903. begin
  904. TheText:=GetAsString;
  905. end;
  906. procedure TBinaryField.SetAsString(const AValue: string);
  907. Var Buf : PChar;
  908. Allocated : Boolean;
  909. begin
  910. Allocated:=False;
  911. If Length(AVAlue)=DataSize then
  912. Buf:=PChar(Avalue)
  913. else
  914. begin
  915. GetMem(Buf,DataSize);
  916. Move(Pchar(Avalue)[0],Buf^,DataSize);
  917. Allocated:=True;
  918. end;
  919. SetData(Buf);
  920. If Allocated then
  921. FreeMem(Buf,DataSize);
  922. end;
  923. procedure TBinaryField.SetText(const AValue: string);
  924. begin
  925. SetAsString(Avalue);
  926. end;
  927. constructor TBinaryField.Create(AOwner: TComponent);
  928. begin
  929. Inherited Create(AOwner);
  930. end;
  931. { TBytesField }
  932. function TBytesField.GetDataSize: Word;
  933. begin
  934. Result:=Size;
  935. end;
  936. constructor TBytesField.Create(AOwner: TComponent);
  937. begin
  938. Inherited Create(AOwner);
  939. SetDataType(ftBytes);
  940. Size:=16;
  941. end;
  942. { TVarBytesField }
  943. function TVarBytesField.GetDataSize: Word;
  944. begin
  945. Result:=Size+2;
  946. end;
  947. constructor TVarBytesField.Create(AOwner: TComponent);
  948. begin
  949. INherited Create(AOwner);
  950. SetDataType(ftvarbytes);
  951. Size:=16;
  952. end;
  953. { TBCDField }
  954. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  955. begin
  956. //!! To be implemented
  957. end;
  958. function TBCDField.GetAsFloat: Extended;
  959. begin
  960. //!! To be implemented
  961. end;
  962. function TBCDField.GetAsLongint: Longint;
  963. begin
  964. //!! To be implemented
  965. end;
  966. function TBCDField.GetAsString: string;
  967. begin
  968. //!! To be implemented
  969. end;
  970. function TBCDField.GetDataSize: Word;
  971. begin
  972. //!! To be implemented
  973. end;
  974. function TBCDField.GetDefaultWidth: Longint;
  975. begin
  976. //!! To be implemented
  977. end;
  978. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  979. begin
  980. //!! To be implemented
  981. end;
  982. procedure TBCDField.SetAsFloat(AValue: Extended);
  983. begin
  984. //!! To be implemented
  985. end;
  986. procedure TBCDField.SetAsLongint(AValue: Longint);
  987. begin
  988. //!! To be implemented
  989. end;
  990. procedure TBCDField.SetAsString(const AValue: string);
  991. begin
  992. //!! To be implemented
  993. end;
  994. constructor TBCDField.Create(AOwner: TComponent);
  995. begin
  996. DatabaseError('BCD fields not supported yet. Sorry !');
  997. end;
  998. { TBlobField }
  999. procedure TBlobField.AssignTo(Dest: TPersistent);
  1000. begin
  1001. //!! To be implemented
  1002. end;
  1003. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  1004. begin
  1005. Result:=FDataset.CreateBlobStream(Self,Mode);
  1006. end;
  1007. procedure TBlobField.FreeBuffers;
  1008. begin
  1009. end;
  1010. function TBlobField.GetAsString: string;
  1011. begin
  1012. With GetBlobStream(bmRead) do
  1013. try
  1014. SetLength(Result,Size);
  1015. ReadBuffer(Pointer(Result)^,Size);
  1016. finally
  1017. Free
  1018. end;
  1019. end;
  1020. function TBlobField.GetBlobSize: Longint;
  1021. begin
  1022. With GetBlobStream(bmread) do
  1023. try
  1024. Result:=Size;
  1025. finally
  1026. Free;
  1027. end;
  1028. end;
  1029. function TBlobField.GetIsNull: Boolean;
  1030. begin
  1031. If Not Modified then
  1032. result:= inherited GetIsnull
  1033. else
  1034. With GetBlobStream(bmread) do
  1035. try
  1036. Result:=(Size=0);
  1037. Finally
  1038. Free;
  1039. end;
  1040. end;
  1041. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  1042. begin
  1043. TheText:=GetAsString;
  1044. end;
  1045. procedure TBlobField.SetAsString(const AValue: string);
  1046. begin
  1047. With GetBlobStream(bmwrite) do
  1048. try
  1049. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1050. finally
  1051. Free;
  1052. end;
  1053. end;
  1054. procedure TBlobField.SetText(const AValue: string);
  1055. begin
  1056. SetAsString(AValue);
  1057. end;
  1058. constructor TBlobField.Create(AOwner: TComponent);
  1059. begin
  1060. Inherited Create(AOWner);
  1061. SetDataType(ftBlob);
  1062. end;
  1063. procedure TBlobField.Assign(Source: TPersistent);
  1064. begin
  1065. //!! To be implemented
  1066. end;
  1067. procedure TBlobField.Clear;
  1068. begin
  1069. GetBlobStream(bmWrite).free;
  1070. end;
  1071. class function TBlobField.IsBlob: Boolean;
  1072. begin
  1073. Result:=True;
  1074. end;
  1075. procedure TBlobField.LoadFromFile(const FileName: string);
  1076. Var S : TFileStream;
  1077. begin
  1078. S:=TFileStream.Create(FileName,fmOpenRead);
  1079. try
  1080. LoadFromStream(S);
  1081. finally
  1082. S.Free;
  1083. end;
  1084. end;
  1085. procedure TBlobField.LoadFromStream(Stream: TStream);
  1086. begin
  1087. With GetBlobStream(bmWrite) do
  1088. Try
  1089. CopyFrom(Stream,0);
  1090. finally
  1091. Free;
  1092. end;
  1093. end;
  1094. procedure TBlobField.SaveToFile(const FileName: string);
  1095. Var S : TFileStream;
  1096. begin
  1097. S:=TFileStream.Create(FileName,fmCreate);
  1098. try
  1099. SaveToStream(S);
  1100. finally
  1101. S.Free;
  1102. end;
  1103. end;
  1104. procedure TBlobField.SaveToStream(Stream: TStream);
  1105. Var S : TStream;
  1106. begin
  1107. S:=GetBlobStream(bmRead);
  1108. Try
  1109. Stream.CopyFrom(S,0);
  1110. finally
  1111. S.Free;
  1112. end;
  1113. end;
  1114. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1115. begin
  1116. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1117. SetDatatype(Avalue);
  1118. end;
  1119. { TMemoField }
  1120. constructor TMemoField.Create(AOwner: TComponent);
  1121. begin
  1122. Inherited Create(AOwner);
  1123. SetDataType(ftMemo);
  1124. end;
  1125. { TGraphicField }
  1126. constructor TGraphicField.Create(AOwner: TComponent);
  1127. begin
  1128. Inherited Create(AOwner);
  1129. SetDataType(ftGraphic);
  1130. end;
  1131. { TFields }
  1132. Constructor TFields.Create(ADataset : TDataset);
  1133. begin
  1134. FDataSet:=ADataset;
  1135. FFieldList:=TList.Create;
  1136. FValidFieldKinds:=[fkData..fkInternalcalc];
  1137. end;
  1138. Destructor TFields.Destroy;
  1139. begin
  1140. FFieldList.Free;
  1141. end;
  1142. Procedure Tfields.Changed;
  1143. begin
  1144. If Assigned(FOnChange) then
  1145. FOnChange(Self);
  1146. end;
  1147. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1148. begin
  1149. If Not (FieldKind in ValidFieldKinds) Then
  1150. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1151. end;
  1152. Function Tfields.GetCount : Longint;
  1153. begin
  1154. Result:=FFieldList.Count;
  1155. end;
  1156. Function TFields.GetField (Index : longint) : TField;
  1157. begin
  1158. Result:=Tfield(FFieldList[Index]);
  1159. end;
  1160. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1161. Var Old : Longint;
  1162. begin
  1163. Old := FFieldList.indexOf(Field);
  1164. If Old=-1 then
  1165. Exit;
  1166. // Check value
  1167. If Value<FFieldList.Count Then Value:=0;
  1168. If Value>=Count then Value:=Count-1;
  1169. If Value<>Old then
  1170. begin
  1171. FFieldList.Delete(Old);
  1172. FFieldList.Insert(Value,Field);
  1173. Field.PropertyChanged(True);
  1174. Changed;
  1175. end;
  1176. end;
  1177. Procedure TFields.Add(Field : TField);
  1178. begin
  1179. CheckFieldName(Field.FieldName);
  1180. FFieldList.Add(Field);
  1181. Field.FFields:=Self;
  1182. Changed;
  1183. end;
  1184. Procedure TFields.CheckFieldName (Const Value : String);
  1185. Var I : longint;
  1186. S : String;
  1187. begin
  1188. If FindField(Value)<>Nil then
  1189. begin
  1190. S:=UpperCase(Value);
  1191. For I:=0 To FFieldList.Count-1 do
  1192. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1193. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1194. end;
  1195. end;
  1196. Procedure TFields.CheckFieldNames (Const Value : String);
  1197. Var I : longint;
  1198. S,T : String;
  1199. begin
  1200. T:=Value;
  1201. Repeat
  1202. I:=Pos(T,';');
  1203. If I=0 Then I:=Length(T);
  1204. S:=Copy(T,1,I-1);
  1205. Delete(T,1,I);
  1206. // Will raise an error if no such field...
  1207. FieldByName(S);
  1208. Until (T='');
  1209. end;
  1210. Procedure TFields.Clear;
  1211. begin
  1212. end;
  1213. Function TFields.FindField (Const Value : String) : TField;
  1214. Var S : String;
  1215. I : longint;
  1216. begin
  1217. Result:=Nil;
  1218. S:=UpperCase(Value);
  1219. For I:=0 To FFieldList.Count-1 do
  1220. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1221. Begin
  1222. {$ifdef dsdebug}
  1223. Writeln ('Found field ',Value);
  1224. {$endif}
  1225. Result:=TField(FFieldList[I]);
  1226. Exit;
  1227. end;
  1228. end;
  1229. Function TFields.FieldByName (Const Value : String) : TField;
  1230. begin
  1231. Result:=FindField(Value);
  1232. If result=Nil then
  1233. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1234. end;
  1235. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1236. Var i : Longint;
  1237. begin
  1238. Result:=Nil;
  1239. For I:=0 to FFieldList.Count-1 do
  1240. If FieldNo=TField(FFieldList[I]).FieldNo then
  1241. begin
  1242. Result:=TField(FFieldList[i]);
  1243. Exit;
  1244. end;
  1245. end;
  1246. Procedure TFields.GetFieldNames (Values : TStrings);
  1247. Var i : longint;
  1248. begin
  1249. Values.Clear;
  1250. For I:=0 to FFieldList.Count-1 do
  1251. Values.Add(Tfield(FFieldList[I]).FieldName);
  1252. end;
  1253. Function TFields.IndexOf(Field : TField) : Longint;
  1254. Var i : longint;
  1255. begin
  1256. Result:=-1;
  1257. For I:=0 To FFieldList.Count-1 do
  1258. If Pointer(Field)=FFieldList[i] Then
  1259. Exit(I);
  1260. end;
  1261. procedure TFields.Remove(Value : TField);
  1262. Var I : longint;
  1263. begin
  1264. I:=IndexOf(Value);
  1265. If I<>0 then
  1266. FFieldList.Delete(I);
  1267. end;
  1268. {
  1269. $Log$
  1270. Revision 1.8 2003-09-14 13:22:14 michael
  1271. + Fixed error in TField.GetCanModify reported by Andrew Johnson
  1272. Revision 1.7 2002/09/07 15:15:23 peter
  1273. * old logs removed and tabs fixed
  1274. }