/*
Copyright (C) 2002-2005 ITK
Author : Uri (uri@itk.ru)
License : (GPL) http://www.itk.ru/clipper/license.html
*/
#include "codb.ch"
#include "codbcfg.ch"
local oDep,oDict
/*
not_null -> notNull
not_empty -> notEmpty
log_need -> logNeed
defvalue -> defValue
extent_id -> extent
super_id -> superClass
expr_essence -> essence
unique_key -> uniqueKey
idx_main -> mainIdx
attr_list -> attributes
idx_list -> indices
attr_find -> findAttrs
ref_to -> refTo
class_id -> class
depend_of -> dependOf
group_id -> group
user_id -> user
col_list -> columns
*/
parameters sDep, className, sData
local s :="",s1:="",s2:="",s3:="",s4:=""
local s5:="",s6:="",s7:="",s8:=""
local isDict := .f.
private files := {}, depends := {}
memvar files, depends
if empty(sDep) //.or. empty(classname) //.or. empty(sData)
? 'Usage: codb_export depository|dictionary ["classname"] ["expression"]'
?
return
endif
set exclusive off
set("PRINTER_EOL","&\n")
sData := iif(sData == NIL, "", sData)
if len(sDep) == DICT_ID_LEN
oDict := coDictionary():new(sDep)
if !empty(oDict:error)
? oDict:error
?
return
endif
oDict:open()
if !empty(oDict:error)
? oDict:error
?
return
endif
oDep := oDict
isDict := .t.
else
oDep:=coDepository():new(sDep)
if !empty(oDep:error)
? oDep:error
?
return
endif
oDep:open()
if !empty(oDep:error)
? oDep:error
?
return
endif
endif
?? __header(oDep,className,sData)
? component_data(oDep,className)
if !empty(classname)
s1 := codb_exportMeta(oDep,className,sData)
endif
if !isDict .and. !empty(className) // oDep:className == "CODBDEPOSITORY"
s2 := codb_exportData(oDep,className,sData)
endif
if isDict .and. empty(className)
s3 := codb_exportDeps(oDep)
endif
? __exportDepend()
? __exportFiles()
if !empty(s1)
? s1
?
endif
if !empty(s2)
? s2
?
endif
if !empty(s3)
? s3
?
endif
? __footer(oDep,className,sData)
?
return
/**********************/
static function codb_exportDeps(oDict)
local i, s1, ret := "", n:= "&\n", s:= "&\t"
local tmp, obj
local m:={"ID","NAME","DTYPE","HOST","PORT","DBUSER","PASSWD","DBNAME"}
ret := s+''+n
for i=1 to len(m)
s1 := m[i]
s1 := lower(s1)
if m[i] $ oDict .and. !empty(oDict[ m[i] ])
ret += s+s+'<'+s1+'>'+oDict[ m[i] ]+''+s1+'>'+n
endif
next
ret += s+s+'$CODBTYPE$'+n
if "PATH" $ oDict .and. !empty(oDict:path)
ret += s+s+'$CODBROOT$'+n
endif
ret += s+''+n+n
ret += s+''+n
tmp := oDict:select("DEPOSIT")
for i=1 to len(tmp)
obj := oDict:getValue(tmp[i])
if empty(obj)
loop
endif
ret += s+s+''+n
next
tmp := oDict:select("EXTENT")
for i=1 to len(tmp)
obj := oDict:getValue(tmp[i])
if empty(obj)
loop
endif
ret += s+s+''+obj:help+''+n
next
ret += s+''+n+n
return ret
/**********************/
static function __exportDepend()
local i, s1, ret := "", n:= "&\n", s:= "&\t"
local x:=map()
ret := s+''+n
for i=1 to len(depends)
if depends[i][2] $ x
loop
endif
ret += s+s+''+depends[i][2]+''+n
x[ depends[i][2] ] := depends[i][2]
next
ret += s+''+n
return ret
/**********************/
static function __exportFiles()
local i, s1, ret := "", n:= "&\n", s:= "&\t"
ret := s+''+n
for i=1 to len(files)
s1 := s+s+''
s1 += files[i][3]+''+n
memowrite(files[i][1],files[i][4])
ret += s1
next
ret += s+''+n+n
return ret
/**********************/
static function component_data(oDep,classname)
local ret := "", n:= "&\n", s:= "&\t"
local oDict,classDesc,extent
oDict := oDep:dictionary()
classDesc := oDict:classBodyByName(className)
if empty(className)
ret += s+''+oDep:id+''+n
ret += s+'CORE/DB'+n
else
ret += s+''+classname+''+n
if !empty(classDesc)
extent := oDict:getValue(classDesc:extent_id)
endif
if !empty(extent)
ret += s+''+extent:name+''+n
endif
endif
ret += s+'1.0'+n
ret += s+'GNU/GPL'+n
ret += s+''+dtoc(date(),"yyyy-mm-dd")+''+n
ret += s+'Uri'+n
ret += s+'ru.Ru'+n
return ret
/**********************/
static function codb_exportMeta(oDep,className,expr)
local oDict,ret := ""
local classDesc
oDict:=oDep:dictionary()
classDesc := oDict:classBodyByName(className)
if empty(classDesc)
ret += __error([Class description not found:]+' '+toString(classname))
return ret
endif
aadd(depends,{"component",oDict:id+"/CORE.xml"})
//aadd(depends,{"component",oDep:id+"/"+CORE+".xml"}})
ret += __exportMeta(oDict,classDesc)
return ret
/**********************/
static function codb_exportData(oDep,className,expr)
local s:="&\t",n:="&\n",ret :=""
local i,j,tmp,obj,attrs:={},m:={}
local name,attr,type,data,s2,s3,s4,s5
local oDict := oDep:dictionary()
local classDesc
classDesc := oDict:classBodyByName(className)
for i=1 to len(classDesc:attr_list)
tmp := oDict:getValue(classDesc:attr_list[i])
if empty(tmp)
loop
endif
aadd(attrs,tmp)
next
if "EXPORT_LIST" $ classDesc .and. !empty(classDesc:export_list)
for i=1 to len(attrs)
if ascan(classDesc:export_list,attrs[i]:name) <=0
aadd(m,i)
endif
next
for i=len(m) to 1 step -1
adel(attrs,m[i])
next
asize(attrs,len(attrs)-len(m))
endif
if empty(expr)
tmp := oDep:select(classDesc:id)
else
tmp := oDep:select(classDesc:id,,,expr)
endif
ret += s+''+n
ret += s+' '+n
for i=1 to len(tmp)
obj := oDep:getValue(tmp[i])
if empty(obj)
ret += __error([Object not found:]+tmp[i])
loop
endif
ret += s+s+''+n
next
ret += s+' '+n
ret += s+''+n
return ret
/**********************/
static function __exportDataArray(oDep,_data,kol)
local _s:="&\t",s,n:="&\n",ret :=""
local i,j,k,type,s1,s2,s3,s4,s5, data, obj
local types := codb_info("CODB_ATTR_TYPES")
s := replicate(_s,kol+1)
ret := n
for i=1 to len(_data)
data := _data[i]
type := valtype(data)
s1:=s2:=s3:=s4:=s5:=""
do case
case type == "N"
s2 := alltrim(str(data))
case type == "D"
s2 := dtos(data)
case type == "L"
s2 := iif(data,"true","false")
case type == "A"
s2 := __exportDataArray(oDep,data,kol+1)
case type == "C"
s2 := data
obj := codb_getValue(data)
if valtype(obj) == "O" .and. "CLASS_ID" $ obj
type := "R"
__metaGetValue(data)
s5 := codb_getRefTo(data)
s2 := codb_getKeyValue(data)
endif
if valtype(obj) == "O" .and. "__META" $ obj
type := "S"
s4 := obj:__meta
s2 := obj:name
s5 := left(obj:id,codb_info("DICT_ID_LEN"))
endif
otherwise
s2 := toString(data)
endcase
k :=""
j := ascan(types,{|x| x[1] == type})
if j > 0
k := types[j][3]
endif
ret += s+''+s2+''+n
next
ret += replicate(_s,kol)
return ret
/**********************/
static function __toString(attr,data)
local ret,type
type := attr:type
do case
case type == "C"
ret := data
case type == "N"
ret := alltrim(str(data))
case type == "D"
ret := dtos(data)
case type == "L"
ret := iif(data,"true","false")
otherwise
ret := toString(data)
endcase
return ret
/**********************/
static function __exportMeta(oDict,classDesc)
local s:="&\t",n:="&\n",ret :=""
local tmp,i,s2,s3,attr,idx
ret += s+''+n
//ret += s+''+n
for i=1 to len(classDesc:attr_list)
attr := oDict:getValue(classDesc:attr_list[i])
if empty(attr)
ret += __error([Object not found:]+classDesc:attr_list[i])
loop
endif
if !empty(attr:counter)
ret += __exportCounter(oDict,attr:counter)
endif
ret += __exportAttr(oDict,attr)
next
//ret += s+''+n
for i=1 to len(classDesc:idx_list)
idx := oDict:getValue(classDesc:idx_list[i])
if empty(idx)
ret += __error([Object not found:]+classDesc:idx_list[i])
loop
endif
ret += __exportIndex(oDict,idx)
next
ret += n+s+s+''+n+n+n
ret += __exportPlugins(oDict,classDesc)
ret += __exportTviews(oDict,classDesc)
ret += s+''+n
return ret
/**********************/
static function __exportPlugins(oDict,classDesc)
local s:="&\t&\t",n:="&\n",ret :=""
local types := codb_info("CODB_PLUGINS_TYPES")
local i,j,k,x,tmp, tmp2, fname
tmp := oDict:select("PLUGINS",,,'class_id=="'+classDesc:id+'"')
for i=1 to len(tmp)
tmp2 := oDict:getValue(tmp[i])
if empty(tmp2)
ret += __error([Object not found:]+tmp[i])
loop
endif
ret += s+' 0
k := types[j][3]
endif
ret += s+s+'type="'+k+'"'+n
fname := tmp2:filename
ret += s+s+'file="'+fname+'"'+n
ret += s+s+'function="'+tmp2:mainfunc+'"'+n
if empty(tmp2:source)
loop
endif
if empty(fname)
fname := classDesc:name+"-"+substr(tmp2:id,codb_info("DICT_ID_LEN")+codb_info("DEPOSIT_ID_LEN"))+".prg"
endif
aadd(files,{fname,"text/clip-source","ODB trigger for class "+classDesc:name,tmp2:source})
ret += s+'/>'+n+n
next
//{"SOURCE" ,"M",0 ,0,CODB_LENTYPE_NONE,""};
return ret
/**********************/
static function __exportTviews(oDict,classDesc)
local ret := "", class_id := classDesc:id
local i,j,k,tmp, tmp2, tcols:={}
tmp := oDict:select("TVIEW",,,'class_id=="'+class_id+'"')
for i=1 to len(tmp)
tmp2 := oDict:getValue(tmp[i])
if empty(tmp2)
ret += __error([Object not found:]+tmp[i])
loop
endif
for j=1 to len(tmp2:col_list)
k := ascan(tcols,tmp2:col_list[j])
if k > 0
loop
endif
aadd(tcols,tmp2:col_list[j])
next
next
tmp2 := oDict:select("TCOLUMN",,classDesc:name)
for i=1 to len(tmp2)
aadd(tCols,tmp2[i])
next
for i=1 to len(tcols)
ret += __exportTcol(oDict,tcols[i])
next
for i=1 to len(tmp)
tmp2 := oDict:getValue(tmp[i])
if empty(tmp2)
ret += __error([Object not found:]+tmp[i])
loop
endif
ret += __exportTview(oDict,tmp2)
next
return ret
/**********************/
static function __exportTview(oDict,tview)
local s:="&\t&\t",n:="&\n",ret :=""
local i,s2,tmp
ret += s+''+n
return ret
/**********************/
static function __exportTcol(oDict,tcol_id)
local s:="&\t&\t",n:="&\n",ret :=""
local i,s2,tcol := oDict:getValue(tcol_id)
if empty(tcol)
ret += __error([Object not found:]+tcol_id)
return ret
endif
ret += s+''+n
return ret
/**********************/
static function __exportCounter(oDict,counter_name)
local s:="&\t&\t",n:="&\n",ret :=""
local tmp,tmp2
tmp := oDict:select("COUNTER",,counter_name)
if empty(tmp)
ret += __error([Counter name not found:]+counter_name)
else
tmp2 := oDict:getValue(tmp[1])
if empty(tmp2)
ret += __error([Object not found:]+tmp[1])
else
ret += s+''+n
endif
endif
return ret
/**********************/
static function __attrType2String(aType)
local types := codb_info("CODB_ATTR_TYPES")
local i,x, ret := "Bad type"
i := ascan(types,{|x|x[1] == aType})
if i<=0
return ret
endif
ret := types[i][3]
return ret
/**********************/
static function __exportAttr(oDict,attr)
local s:="&\t&\t",ss:="&\t",n:="&\n",ret :=""
local tmp,i,x,s2,s3:=""
local m :={"ignore","rtrim","alltrim","fill"}
ret += s+' 0 .and. attr:lentype <= len(m)
x := m [ attr:lentype ]
else
x := m[1]
endif
ret += ss+'lenType="'+x+'"'+n
ret += s+ss+'len="'+alltrim(str(attr:len))+'"'
ret += ss+ss+'dec="'+alltrim(str(attr:dec))+'"'+n
ret += s+ss+'mask="'+attr:mask+'"'
ret += s+ss+'defValue="'+attr:defvalue+'"'+n
if !empty(attr:counter)
ret += s+ss+'counter="'+attr:counter+'"'+n
endif
ret += s+ss+'notNull="'+iif(attr:not_null,"true","false")+'"'
ret += s+'notEmpty="'+iif(attr:not_empty,"true","false")+'"'+n
if !empty(attr:source)
ret += s+ss+'source="'+var2str(attr:source)+'"'+n
endif
if !empty(attr:code)
ret += s+ss+'code="'+var2str(attr:code)+'"'+n
endif
if !empty(attr:help)
ret += s+ss+'help="'+var2str(attr:help)+'"'+n
endif
if !empty(attr:ref_to)
s2 := left(attr:ref_to,codb_info('DICT_ID_LEN'))+':'
tmp := __metagetValue(attr:ref_to)
if empty(tmp)
s3 += __error([Object not found:]+attr:ref_to)
else
s2+=tmp:name
endif
aadd(depends,{"component",strtran(s2,":","/")+".xml"})
ret += s+ss+'refTo="'+s2+'"'+n
endif
ret += n+s+'/>'+n
//ret += s+'>'+attr:name+''+n
if !empty(s3)
ret += s3
endif
return ret
/**********************/
static function __exportIndex(oDict,idx)
local s:="&\t&\t",n:="&\n",ret :=""
local tmp,i,s2,s3:=""
ret += s+''+n
return ret
/**********************/
static function __header(oDep,className,expr)
local ret := ""
ret+='&\n'
/*
ret+='&\n'
ret+='&\n'
*/
ret+='&\n'
ret+= ''+'&\n'
return ret
static function __footer(oDep,className,expr)
local ret := ""
ret+= ''+'&\n'
return ret
/**********************/
static function __error(s)
return '&\n'
/**********************/
static function __metaGetValue(cID)
local oDict, dict_id:=left(cID,codb_info('DICT_ID_LEN'))
oDict := codb_dict_reference(dict_id)
if valtype(oDict) != "O"
oDict := coDictionary():new(dict_id)
if empty(oDict:error)
oDict:open()
if !empty(oDict:error)
oDict:close()
oDict := NIL
endif
else
oDict := NIL
endif
endif
if valtype(oDict) != "O"
return cId
endif
return oDict:getValue(cId)
/**********************/
static function __entityTran(str)
local ret := str
local j, e := {{"&","&"},{">",">"},{"<","<"}}
for j=1 to len(e)
ret := strtran(ret,e[j][2],e[j][1])
next
return ret