/pliant/storage/database/prototype.pli
 
 1  abstract 
 2    [Pliant database engine is based on an abstract interface (a set of generic methods) used to access real datas which type is not known by the application that access them. ] ; eol 
 3    [This module defines the interface methods.] 
 4   
 5  # Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx 
 6  # 
 7  # This program is free software; you can redistribute it and/or 
 8  # modify it under the terms of the GNU General Public License version 2 
 9  # as published by the Free Software Foundation. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # version 2 along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 19   
 20  module "/pliant/language/compiler.pli" 
 21  module "/pliant/language/data/string_cast.pli" 
 22  module "/pliant/util/encoding/html.pli" 
 23   
 24  module "/pliant/language/compiler/type/inherit.pli" 
 25  module "/pliant/language/data/cache.pli" 
 26  module "/pliant/language/stream.pli" 
 27   
 28  constant autocreate false 
 29   
 30  public 
 31   
 32  (gvar TraceSlot database_trace) configure "database" 
 33   
 34  type DataInterface_ 
 35    void 
 36   
 37  flagset DatabaseFlags 
 38    database_loading 
 39    database_modified 
 40    database_compressed 
 41    database_autoclose 
 42    database_autostore 
 43   
 44  type Database_ 
 45    inherit CachePrototype 
 46    field Pointer:Sem sem 
 47    field Str path 
 48    field DatabaseFlags flags 
 49   
 50  CachePrototype maybe Database_ 
 51   
 52  type DataScanBuffer 
 53    field Int int 
 54    field Address adr 
 55    field Arrow arrow 
 56   
 57   
 58 
 
 59   
 60  doc 
 61    fixed [Data_ ] [is pointer to a data in the database.] ; eol 
 62    [It contains:] 
 63    list 
 64      item 
 65        [The address of the true data (but the true data type is unknown). See] ; fixed [ DataInterface_ ] [below.] 
 66      item [An arrow to the object that contains the data. This will prevent the data to be freed as long as we have a pointer to it.] 
 67      item [The interface that is an object that contains the generic methods that will be used to access the data.] 
 68      item [The base is the pointer to database the data belongs to.] 
 69      item [The data path (a string like a file path that identify the object and can be used to get an access to it) is stored in two parts for speed reasons.] 
 70   
 71   
 72  type Data_ 
 73    field Address adr 
 74    field Arrow object 
 75    field Link:DataInterface_ interface 
 76    field Link:Database_ base 
 77    field Link:Str path1 
 78    field Pointer:Str path2 
 79   
 80   
 81  gvar DataInterface_ empty_interface 
 82  gvar Database_ empty_database 
 83  gvar Sem empty_sem 
 84  empty_database sem :> empty_sem 
 85  gvar Str empty_string 
 86   
 87  function build d 
 88    arg_w Data_ d 
 89    adr := null 
 90    interface :> empty_interface 
 91    base :> empty_database 
 92    path1 :> empty_string 
 93    path2 :> null map Str 
 94   
 95  gvar Data_ data_null 
 96   
 97  method d key -> k 
 98    arg Data_ d ; arg Str k 
 99    if (exists d:path2) 
 100      := html_decode (d:path2 d:path2:len) 
 101    else 
 102      var Int := d:path1 search_last "/" -1 
 103      := html_decode (d:path1 i+d:path1:len) 
 104   
 105  method d dbpath -> p 
 106    arg Data_ d ; arg Str p 
 107    if (exists d:path2) 
 108      := d:path1+d:path2 
 109    else 
 110      := d:path1 
 111   
 112  method d path -> p 
 113    arg Data_ d ; arg Str p 
 114    if (exists d:path2) 
 115      := d:base:path+d:path1+d:path2 
 116    else 
 117      := d:base:path+d:path1 
 118   
 119   
 120 
 
 121   
 122  doc 
 123    [The data that pointed by] ; fixed [ Data_ ] [is of an unknown real type, so we must use generic methods to access it. ] 
 124    [Also the data pointed is not always a true object (a field in a record is not, for memory compactness reasons), so instead od calling the generic method on the data directely, we use the link to the] ; fixed [ DataInterace_ ] [object which is stored in the] ; fixed [ Data_ ] [pointer, and call the generic method in this one.] ; eol 
 125    [You could see the] ; fixed [ DataInterface_ ] [as a functions array.] 
 126   
 127   
 128  method di type d -> t 
 129    oarg DataInterface_ di ; arg Data_ d ; arg_R Type t 
 130    generic 
 131    # get the physical type of the data associated with this node 
 132    :> Void 
 133   
 134  method di get d adr type -> status 
 135    oarg DataInterface_ di ; arg Data_ d ; arg Address adr ; arg Type type ; arg Status status 
 136    generic 
 137    # try to read the data associated with this node, and cast it to the specify type 
 138    status := failure 
 139    # 
 140    # the following seems to be both buggy (using 'object' instead of 'adr') and of no use, 
 141    # I just comment it out since I can't remember why I wrote it, so it might be of some use anyway. 
 142     
 143    # if d:object<>null 
 144    #   if type=(entry_type d:object) 
 145    #     type copy_instance d:object adr 
 146    #   else 
 147    #     var Str s := to_string d:object (entry_type d:object) "db" 
 148    #     from_string adr type s "db" 
 149   
 150  method di set d adr type -> status 
 151    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Address adr ; arg Type type ; arg Status status 
 152    generic 
 153    # try to set the data associated with this node to the provided typed value 
 154    status := failure 
 155   
 156  method di reset d -> status 
 157    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Status status 
 158    generic 
 159    # resets the subtree starting at this node 
 160    status := failure 
 161   
 162   
 163  method di search d k -> d2 
 164    oarg DataInterface_ di ; arg Data_ d ; arg Str k ; arg Data_ d2 
 165    generic 
 166    # get a link to the node at the end of the edge with the provided name 
 167    d2 := data_null 
 168    d2 base :> base 
 169    d2 path1 :> new Str d:dbpath+"/"+html_encode:k 
 170    d2 path2 :> null map Str 
 171   
 172   
 173  method di first d start stop buf -> d2 
 174    oarg DataInterface_ di ; arg Data_ d ; arg Str start stop ; arg_w DataScanBuffer buf ; arg Data_ d2 
 175    generic 
 176    # get a link to the first son in the tree which key is >=start and <stop 
 177    # (stop is ignore if it's len is zero) 
 178    # (returns data_null node if none is matching the constains) 
 179    d2 := data_null 
 180   
 181  method di next d start stop buf -> d2 
 182    oarg DataInterface_ di ; arg Data_ d ; arg Str start stop ; arg_rw DataScanBuffer buf ; arg Data_ d2 
 183    generic 
 184    # get a link to the next son that still match the constains 
 185   
 186  method di count d start stop -> count 
 187    oarg_rw DataInterface_ di ; arg Data_ d ; arg Str start stop ; arg Int count 
 188    generic 
 189    # get the number of sons that match the constains 
 190    count := 0 
 191   
 192   
 193  method di create d k -> status 
 194    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Str k ; arg Status status 
 195    generic 
 196    # creates a new node 
 197    status := failure 
 198   
 199  method di delete d k -> status 
 200    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Str k ; arg Status status 
 201    generic 
 202    # deletes the subtree starting at the node at the end of the edge with the provided name 
 203    status := failure 
 204   
 205   
 206 
 
 207   
 208   
 209  method di search d k createit -> d2 
 210    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Str k ; arg CBool createit ; arg Data_ d2 
 211    d2 := di search k 
 212    if d2:adr=null and createit 
 213      if (di create k)=success 
 214        d2 := di search k 
 215   
 216   
 217  method di first_to_store d start stop buf -> d2 
 218    oarg DataInterface_ di ; arg Data_ d ; arg Str start stop ; arg_w DataScanBuffer buf ; arg Data_ d2 
 219    generic 
 220    d2 := di first start stop buf 
 221   
 222  method di next_to_store d start stop buf -> d2 
 223    oarg DataInterface_ di ; arg Data_ d ; arg Str start stop ; arg_rw DataScanBuffer buf ; arg Data_ d2 
 224    generic 
 225    d2 := di next start stop buf 
 226   
 227   
 228  method di pre_delete d k 
 229    arg DataInterface_ di ; arg Data_ d ; arg Str k 
 230    generic 
 231   
 232   
 233  method di get_raw d adr type -> status 
 234    oarg DataInterface_ di ; arg Data_ d ; arg Address adr ; arg Type type ; arg Status status 
 235    generic 
 236    status := di get adr type 
 237   
 238  method di set_raw d adr type -> status 
 239    oarg_rw DataInterface_ di ; arg_rw Data_ d ; arg Address adr ; arg Type type ; arg Status status 
 240    generic 
 241    status := di set adr type   
 242   
 243   
 244 
 
 245   
 246  doc 
 247    [The] ; fixed [ Database_ ] [type defines the generic methods that a] ; fixed [ Data_ ] [will use to notify the database that a data has been modifyed.] 
 248   
 249  method db update stream -> status 
 250    oarg_rw Database_ db ; arg_rw Stream stream ; arg ExtendedStatus status 
 251    generic 
 252    status := failure "not implemented" 
 253   
 254  method db dump stream -> status 
 255    oarg_rw Database_ db ; arg_rw Stream stream ; arg ExtendedStatus status 
 256    generic 
 257    status := failure "not implemented" 
 258   
 259  method db sleep 
 260    oarg_rw Database_ db 
 261    generic 
 262   
 263  method db drop 
 264    oarg_rw Database_ db 
 265    generic 
 266   
 267  method db get_root d 
 268    arg Database_ db ; arg_w Data_ d 
 269    generic 
 270    := data_null 
 271   
 272  method db notify_set d adr type 
 273    arg_rw Database_ db ; arg Data_ d ; arg Address adr ; arg Type type 
 274    generic 
 275   
 276  method db notify_reset d 
 277    arg_rw Database_ db ; arg Data_ d 
 278    generic 
 279   
 280  method db notify_create d k 
 281    arg_rw Database_ db ; arg Data_ d ; arg Str k 
 282    generic 
 283   
 284  method db notify_delete d k 
 285    arg_rw Database_ db ; arg Data_ d ; arg Str k 
 286    generic 
 287   
 288  method db query command -> answer 
 289    oarg Database_ db ; arg Str command answer 
 290    generic 
 291    answer := "" 
 292   
 293  method db configure command -> status 
 294    oarg_rw Database_ db ; arg Str command ; arg Status status 
 295    generic 
 296    status := failure