fields.inc 29 KB

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