home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / www / afc / afc-dir / database_examples.lha / Examples / dbfdate.e < prev    next >
Text File  |  1998-04-05  |  7KB  |  238 lines

  1. /*
  2.   AFCDataBase custom field: Date    by Andrea Galimberti  -  (C) Brighting Brain Brothers
  3.  
  4.  
  5.   ID:             DBFIELD_DATE
  6.  
  7.   OBJECT NAME:    dbfdate
  8.  
  9.   CONTENT:        string
  10.  
  11.   LENGTH (bytes): 10
  12.  
  13.   INDEX:          any
  14.  
  15.   METHODS:        all methods available
  16.  
  17.  
  18.   Note: This example of a possible "date" field stores the date in a string
  19.         format. The setv() method only reformats the date using two slash
  20.         characters to separate the day, month and year part (in this order).
  21.         Besides, the date field is searched (indexed or not) using the
  22.         built-in string matching routines: an evident drawback is that the
  23.         year 1998 is different from 98 (!).
  24.  
  25.         Probably, a more useful "date" field will store the date in a
  26.         Julian date format: the string entered by the user may be converted
  27.         automatically by the setv() method; the getv() method may return the
  28.         Julian date number, and the asString() method may reformat this
  29.         number in a string. Doing so, the search for a date is done using the
  30.         built-in number searching routines (DBIDXVALUE_NUMBER, and
  31.         DBSEARCH_NUMBER).
  32. */
  33.  
  34. OPT MODULE
  35. OPT EXPORT
  36.  
  37. MODULE 'afc/database'
  38.  
  39. /* our new field type (inherited from dbfield) */
  40. OBJECT dbfdate OF dbfield PRIVATE
  41.   value:PTR TO CHAR  -> this is the place where we are going to store the
  42.                      -> field value
  43. ENDOBJECT
  44.  
  45. /* the constant identifing our new field type. This is used when the
  46.    end-user adds to his table a field of this type. */
  47. CONST DBFIELD_DATE="fDAT"
  48.  
  49.  
  50. -> Constructor and destructor
  51.  
  52.  
  53. /* The field contructor: note that it is a procedure, not a method */
  54. PROC builder(tag:PTR TO LONG)
  55.   DEF f=NIL:PTR TO dbfdate
  56.  
  57.   NEW f.dbfield(tag)  -> here we call the base-class constructor
  58.   IF f=NIL THEN Raise(DBASE_ERR_NOMEM)
  59.   /* the length of a date field has to be always of 10 bytes, so we
  60.      override the DBFTAG_LENGTH passed in the taglist */
  61.   f.setattrs([DBFTAG_LENGTH,10,NIL,NIL])
  62.   /* we allocate the memory to store the field value*/
  63.   f.value:=String(f.getattr(DBFTAG_LENGTH))
  64.   IF f.value=NIL THEN Raise(DBASE_ERR_NOMEM)
  65. ENDPROC f  -> Important: we return the pointer to the instance of the field
  66.  
  67. /* The field destructor */
  68. PROC end() OF dbfdate
  69.  
  70.   /* Dispose the memory allocated for the field value */
  71.   IF self.value THEN DisposeLink(self.value)
  72.   SUPER self.end()  -> remember to call the base-class destructor
  73. ENDPROC
  74.  
  75.  
  76. -> methods to set/get, write/read the field contents
  77.  
  78.  
  79. /* The following methods normalize_date() and check_slash() are simply
  80.    functions used by the setv() method to parse and reformat a date */
  81. PROC normalize_date(s,f,l) OF dbfdate
  82.   DEF d[10]:STRING, m[10]:STRING, y[10]:STRING
  83.   DEF dv=0, mv=0, yv=0, dd=NIL:PTR TO LONG
  84.  
  85.   MidStr(d,s,0,f)
  86.   MidStr(m,s,f+1,l-f-1)
  87.   RightStr(y,s,StrLen(s)-l-1)
  88.   dv:=Val(d)
  89.   mv:=Val(m)
  90.   yv:=Val(y)
  91.  
  92.   dd:=[31,28,31,30,31,30,31,31,30,31,30,31]
  93.   IF mv<1 THEN mv:=1
  94.   IF mv>12 THEN mv:=12
  95.   IF dv<1 THEN dv:=1
  96.   IF dv>dd[mv-1] THEN dv:=dd[mv-1]
  97.   StringF(s,'\z\d[2]/\z\d[2]/\d',dv,mv,yv)
  98. ENDPROC s
  99.  
  100. PROC check_slash(s,q) OF dbfdate
  101.   DEF f=0,l=0, left[10]:STRING, right[10]:STRING
  102.   DEF x[10]:STRING
  103.  
  104.   StrCopy(x,s)
  105.   f:=InStr(x,q,0)
  106.   IF f>=0
  107.     l:=InStr(x,q,f+1)
  108.     IF l>=0
  109.       StrCopy(x,self.normalize_date(x,f,l))
  110.     ELSE
  111.       MidStr(left,x,0,f+3)
  112.       RightStr(right,x,StrLen(x)-f-3)
  113.       StringF(x,'\s/\s',left,right)
  114.       l:=f+3
  115.       StrCopy(x,self.normalize_date(x,f,l))
  116.     ENDIF
  117.   ELSE
  118.     StrCopy(x,'')
  119.   ENDIF
  120. ENDPROC x
  121.  
  122. /* This sets the field value */
  123. PROC setv(v) OF dbfdate
  124.   DEF z[10]:STRING, left[10]:STRING, right[10]:STRING
  125.   DEF f=0, l=0
  126.  
  127.   SUPER self.setv(v)
  128.   /* we call strClear to zero all the string bytes (StrCopy(self.value,'')
  129.      will only set the string length to 0) */
  130.   strClear(self.value)
  131.  
  132.   -> here you can do all your processing before storing the value...
  133.  
  134.   StrCopy(z,self.check_slash(v,'/'))
  135.   IF StrCmp(z,'')
  136.     StrCopy(z,self.check_slash(v,'-'))
  137.     IF StrCmp(z,'')
  138.       MidStr(left,v,0,2)
  139.       MidStr(z,v,2,2)
  140.       RightStr(right,v,StrLen(v)-4)
  141.       StringF(v,'\s/\s/\s',left,z,right)
  142.       f:=2
  143.       l:=5
  144.       StrCopy(z,self.normalize_date(v,f,l))
  145.     ENDIF
  146.   ENDIF
  147.  
  148.   StrCopy(self.value,z)
  149. ENDPROC TRUE  -> always return TRUE
  150.  
  151. /* Returns the contents of the field */
  152. PROC getv() OF dbfdate IS self.value
  153.  
  154. /* Clears the contents of the field */
  155. PROC clear() OF dbfdate
  156.  
  157.   SUPER self.clear()
  158.   strClear(self.value)
  159. ENDPROC
  160.  
  161. /* Writes the field contents to the database file */
  162. PROC write(owner) OF dbfdate
  163.  
  164.   /* Note how we check the return value of the supermethod before writing
  165.      anything to file; then we write DBFTAG_LENGTH bytes from self.value.
  166.      The owner parameter is needed in I/O routines to identify the database
  167.      file to which we are going to write. */
  168.   IF SUPER self.write(owner) THEN self.fwrite(owner,self.value,self.getattr(DBFTAG_LENGTH))
  169. ENDPROC
  170.  
  171. /* Reads the field contents from the database file */
  172. PROC read(owner) OF dbfdate
  173.  
  174.   SUPER self.read(owner)
  175.   /* Read DBFTAG_LENGTH bytes to self.value */
  176.   self.fread(owner,self.value,self.getattr(DBFTAG_LENGTH))
  177. ENDPROC TRUE  -> return FALSE if something went wrong
  178.  
  179. /* Converts the field contents to a string and stores them in the string
  180.    passed as a parameter */
  181. PROC asString(s:PTR TO CHAR) OF dbfdate
  182.  
  183.   IF s THEN StrCopy(s, self.value)
  184. ENDPROC s  -> return the same string you received as a parameter
  185.  
  186.  
  187. -> Index methods
  188.  
  189.  
  190. /* We store the date as a string, so we specify that the index must be
  191.    searched using the built-in string matching routines (Obviously this
  192.    works if the end-user adds an index for this type of field; otherwise
  193.    the search style is specified by the searchtype() method) */
  194. PROC idxvaluetype() OF dbfdate IS DBIDXVALUE_STRING
  195.  
  196. /* This method returns the value to be added to the field index */
  197. PROC idxvalue() OF dbfdate
  198.   DEF s=NIL
  199.  
  200.   /* We allocate the memory for the index value (string) and copy the
  201.      field contents */
  202.   s:=String(self.getattr(DBFTAG_LENGTH))
  203.   IF s=NIL THEN Raise(DBASE_ERR_NOMEM)
  204.   StrCopy(s, self.value)
  205. ENDPROC s  -> return the index item allocated
  206.  
  207. /* Free the memory of the index item allocated with the previous method */
  208. PROC idxdisposevalue(p) OF dbfdate
  209.  
  210.   IF p THEN DisposeLink(p)
  211. ENDPROC
  212.  
  213. /* Writes the index value to the index file */
  214. PROC writeidxvalue(owner, v) OF dbfdate
  215.  
  216.   self.fwrite(owner,v,self.getattr(DBFTAG_LENGTH))
  217. ENDPROC
  218.  
  219. /* Reads the index value from the index file */
  220. PROC readidxvalue(owner) OF dbfdate
  221.   DEF s=NIL
  222.  
  223.   /* We have to allocate the memory to store the index item */
  224.   s:=String(self.getattr(DBFTAG_LENGTH))
  225.   IF s=NIL THEN Raise(DBASE_ERR_NOMEM)
  226.   /* Then we read it from the file */
  227.   self.fread(owner,s,self.getattr(DBFTAG_LENGTH))
  228. ENDPROC s  -> and return the index item just read
  229.  
  230.  
  231. -> Other methods
  232.  
  233.  
  234. /* This specifies that if the field is not indexed the database engine uses
  235.    the built-in string matching routines to search for a value */
  236. PROC searchtype() OF dbfdate IS DBSEARCH_STRING
  237.  
  238.