Patch title: CSV <-> database
Abstract:
Sample application for CSV interchange with Pliant database
File: /DataBase/newcsv.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/unsafe.pli"
submodule "/pliant/language/stream.pli"
submodule "/pliant/appli/database.pli"


public

type CSVDatabase
   field Set:Str fields        # nom des colonnes, cl齴o_key (n° colonne)
   field Set:(Set Str) values  # valeurs; permi貥 cl麠to_key (n° de ligne), 
   #                               deuxi譥 cl麠to_key (N° colonne)

# ces deux fonctions ont pour but de pr鳥rver l'ordre des lignes 
# dans l'ordre lexicographique des cl鳮 (鶩ter que la ligne 2 se trouve apr鳠la ligne 11)
# l'entier i (N° de ligne ou de colonne) est cod頳ous forme d'une chaine de caract貥
# correspondant ࠬa valeur en base 32 (pour prendre moins de place)
# toutes les chaines sont 飲ites avec le mꭥ nombre de caract貥s
# (ajout d'un certain nombre de 0 en t괥 si n飥ssaire)

# conversion entier -> clé

function to_key i -> k
  arg Int i; arg Str k
  k := string i "radix 32"
  constant nx (Int:bitsize+4)\5
  k := (repeat nx-k:len "0")+k

# conversion cl頭> entier

function to_int k -> i
  arg Str k; arg Int i
  var Int v := 0
  for (var Int x) 0 k:len-1
    v := 32*v+(k:x:number-(shunt k:x<"A" "0":number "A":number-10))
  return v

doc
  [Fonction de cr顴ion d'un fichier CSV ࠰artir de la Base de Donn饳 ]; eol
  table columns 2
     cell header [argument]
     cell header [signification]
     cell [pdb]
     cell [Pointeur base de donn饳 (ex: mabase:data)]
     cell [delim]
     cell [delimiteur ࠵tiliser]
     cell [out]
     cell [Flux de sortie]

function to_csv pdb delim out
  arg Data:CSVDatabase pdb; arg Str delim; arg_rw Stream out
  # 飲iture des nom des champs
  var Bool first := true
  each h pdb:fields
    if not first
      out writechars delim
    else
      first := false
    out writechars h
  out writechars "[lf]"

  # 飲iture des donn饳
  each record pdb:values
    first := true
    each v record
      if not first
        out writechars delim
      else
        first := false
      out writechars v
    out writechars "[lf]"

doc
  [Transforme un fichier CSV en base de donn饳. La premi貥 ligne doit contenir les noms des champs]
  table columns 2
     cell header [argument]
     cell header [signification]
     cell [in]
     cell [Flux d'entr饝
     cell [delim]
     cell [delimiteur ࠵tiliser]
     cell [pdb]
     cell [Pointeur base de donn饳 (ex: mabase:data)]

function to_db in delim pdb
  arg_rw Stream in; arg Str delim; arg_rw Data:CSVDatabase pdb
  # d'abord: on efface tout dans la base.
  data_reset pdb
  # parse les nom de champs
  var Str line := in:readline+delim # on ajoute un delimiteur en fin de ligne
  #                                   pour faciliter le parsing
  var Int nc := 0 # numero de colonne (on commence ࠰, par coh鲥nce avec les array)
  while (line parse any:(var Str h) pattern:delim any:line)
    var Str kc := to_key nc # cl頣orrespondant ࠮c
    pdb:fields create kc
    pdb:fields kc := h
    nc += 1
  var Int nr := 0 # numero de record
  while not in:atend
    var Str kr := to_key nr
    pdb:values create kr
    var Data:(Set Str) record :> pdb:values:kr
    line := in:readline+delim
    nc := 0
    while (line parse any:(var Str value) pattern:delim any:line)
      kc := to_key nc # cl頣orrespondant ࠮c
      record create kc
      record:kc := value
      nc += 1
    nr += 1
# FIN