# # ITSV GmbH # CCDB - Command and Control Database # # FILE: dquerymfile_exporttext.txt # DESCRIPTION: DQUERY definition for DQUERY exporttext # this query exports a text, consisting of one or mode text fragments in CCDB table CCTEXTFRAG # @querytitle Liste von vorhandenen CCDB-notepads @querydescription Diese Abfrage exportiert einen Text aus CCDB-Text-Fragmenten @attributenames textident:string:{{textidentoptions}},exportformat:string:{{exportformatoptions}},toptextident:string:{{toptextidentoptions}},dbgout:yesno:{{dbgoutoptions}} @textidentoptions { labeltext: "Texts-ID", typedesc: "\"ident\" des Text-Knotens in der CCDB-Tabelle CCTEXTFRAG, der exportiert werden soll" } @exportformatoptions { labeltext: "Export-Format", typedesc: "Format, in dem der Export des Texts erstellt werden soll" } @toptextidentoptions { labeltext: "Top-Level-ID", typedesc: "\"ident\" des obersten Text-Knotens in der Gesamt-Struktur, wird beim rekursiven Aufruf verwendet, beim Top-Level-Aufruf nicht angegeben", is_optional: true } @dbgoutoptions { labeltext: "Debugging", typedesc: "Wenn aktiv, wird Debug-Information ausgegeben", is_optional: true } @querytype function @function seqtrans.seqtrans @sqlmac_RKSR_hide update "reporttype" set "name"=::hidden_name_q::,"role"='INVISIBLE' where "name"=::name_q:: and type = 'USER'; @sqlmac_RKSR_insert insert into "reporttype"("sql", "version", "Erstelldatum", "role", "type", "name", "personenbezug") values(::sql_q::, 1, NOW(), ::role_q::, 'USER', ::name_q::, ::personenbezug_bs::); @init.qexpression this.removeEmptyLines = function(dl) { let rdl = new Array(); for (let i = 0; i < dl.length; i++) { if (dl[i]) rdl.push(dl[i]); } return rdl; }.bind(this); this.normalizeFragmentData = function(s) { return (s+"").replace(/\{\{double_colons\}\}/g,"::").replace(/\n\r/g,"\r\n").replace(/\r\n/g,"\n").replace(/\r/g,"\n"); }.bind(this); this.allPrintable = function(s) { let res = ""; let cc; let lastcc = 0; let nextcc = 0; for (let i = 0; i < s.length; i++) { cc = s.charCodeAt(i); nextcc = (i126)) { res += "<" + cc + ">"; } else { res += String.fromCharCode(cc); } if (((cc==10) && (lastcc==13)) || ((cc==13) && (lastcc==10)) || ((lastcc!=10) && (lastcc!=13) && (cc==10) && (nextcc!=10) && (nextcc!=13)) || ((lastcc!=13) && (lastcc!=10) && (cc==13) && (nextcc!=13) && (nextcc!=10))) { res += this.linesep; } lastcc = cc; } return res; }.bind(this); this.addToLastLine = function(intext, addtext) { if (intext.endsWith(this.linesep)) { let indx = intext.length-(this.linesep.length); return intext.substr(0,indx) + addtext + this.linesep; } else { return intext + this.linesep; } }.bind(this); this.isCreateView = function(s) { let viewname = ""; let re = new RegExp("create\\sor replace\\sview\\s([A-Za-z0-9_\\\"]*)\\sas"); let vn = null; let m = re.exec(s); logger.debug("exporttext.isCreateView: "+aux.objTxt({ text: s, match: m},99,999999)); if (m) { if (m.length>1) { viewname = m[1]; } else { viewname = '???MatchButViewnameNotCaptured???'; } } return viewname; }.bind(this); this.quoteSingle = function(s) { return "'" + (s+"").replace(/\'/g,"''") + "'"; }.bind(this); this.addQuoteSingleAll = function(o) { for (anam in o) { o[anam+"_q"] = this.quoteSingle(o[anam]); } }.bind(this); this.renderNode = function(dbres,exportformat,opts) { let res = ""; let rowdata = null; if (!opts) opts = {}; if (!opts.linesep) opts.linesep = "\r\n"; let ci = 0; let fi; let rd; let rdl; let lasttype = "UNKNOWN"; let thistype = "UNKNOWN"; for (let rownum = 0; rownum0) { if (this.dbgout) { res += "-- \"" + rdl.join("\"" + opts.linesep + "-- \"") + "\"" + opts.linesep; } else { res += "-- " + rdl.join(opts.linesep + "-- ") + opts.linesep; } } } else if (rowdata.type=="SQLSEQ") { rd = this.normalizeFragmentData(rowdata.data); if ((this.dbgout) && ((rowdata.data.indexOf("kfoqsdb.alignuencnames")>=0) || (rowdata.data.indexOf("replace view V_QSE_EXPORT")>=0))) { res += "-- ---- raw fragment data:" + this.linesep; let rrdl = this.allPrintable(rowdata.data).split(this.linesep); res += "-- ---- " + rrdl.join(this.linesep + "-- ---- ") + this.linesep; res += "-- ---- normalized fragment data:" + this.linesep; rrdl = this.allPrintable(rd).split(this.linesep); res += "-- ---- " + rrdl.join(this.linesep + "-- ---- ") + this.linesep; } rdl = rd.split("\n"); if (this.dbgout) res += "-- ---- " + rowdata.type + " text fragment has " + rdl.length + " text lines, last line is \"" + rdl[rdl.length-1] + "\"" + opts.linesep; if (rdl.length>0) { if (this.dbgout) { res += "\"" + rdl.join("\"" + opts.linesep + "\"") + "\"" + opts.linesep; } else { res += rdl.join(opts.linesep) + opts.linesep; } } } else if (rowdata.type=="SQLTEST") { res += "-- Test-Prozedur: " + this.linesep; rd = this.normalizeFragmentData(rowdata.data); rdl = rd.split("\n"); if (this.dbgout) res += "-- ---- " + rowdata.type + " text fragment has " + rdl.length + " text lines, last line is \"" + rdl[rdl.length-1] + "\"" + opts.linesep; if (rdl.length>0) { if (this.dbgout) { res += "-- \"" + rdl.join("\"" + opts.linesep + "-- \"") + "\"" + opts.linesep; } else { res += "-- " + rdl.join(opts.linesep + "-- ") + opts.linesep; } } else { res += "-- (nicht definiert) " + this.linesep; } } else if (rowdata.type=="SQLMAC") { if (this.dbgout) res += "-- ---- SQLMAC fragment, data: \"" + rowdata.data + "\"" + opts.linesep; let mac; try { eval("mac = " + rowdata.data); } catch (e) { throw new Error("Error parsing SQLMAC descriptor in " + aux.objTxt(rowdata) ); return; } if (mac.macro=="registerKFOQSDBreport") { mac.hidden_name = "hidden_"+mac.name; this.addQuoteSingleAll(mac); mac.personenbezug_bs = mac.personenbezug?"true":"false"; res += "-- Definition von KFOQSDB report \""+mac.name+"\": alte Definition(en) werden \"hidden\", neue angelegt" + opts.linesep; res += aux.populate({ template: this.query.sqlmac_RKSR_hide, delimname: "double_colons", data: mac, adata: this}) + opts.linesep; res += aux.populate({ template: this.query.sqlmac_RKSR_insert, delimname: "double_colons", data: mac, adata: this}) + opts.linesep; } else { throw new Error("illegal SQLMAC macro name from rowdata "+aux.objTxt(rowdata)); return; } } else { throw new Error("illegal text fragment type \"" + rowdata.type + "\" in row " + rownum); return; } } lasttype = thistype; fi++; } if ((exportformat=="REPDEFSQL") && (thistype=="SQLSEQ")) { res = this.addToLastLine(res,";"); let viewname; if (viewname = this.isCreateView(res)) { viewname = viewname.replace(/\"/g,""); res += "alter view \"" + viewname + "\" owner to kfoqsdb;" + opts.linesep; } } return res; }.bind(this); ~query.tsteps # # <>: setup # qexpression proc: { this.res = ""; if (this.query.textident) { this.ident = this.query.textident; } else { this.errcoll.collect(null,"no textident given",{ query: this.query }); break proc; } if (this.query.exportformat) { this.exportformat = this.query.exportformat; } else { this.errcoll.collect(null,"no exportformat given",{ query: this.query }); break proc; } if (this.query.toptextident) { this.toptextident = this.query.toptextident; } else { this.toptextident = this.ident; } this.ppush([ this.phead("START"), "TEXTIDENT=" + this.ident, "EXPORTFORMAT=" + this.exportformat, "TOPTEXTIDENT=" + this.toptextident ]); if (this.exportformat=="REPDEFSQL") { this.linesep = "\r\n"; if (this.ident==this.toptextident) { if (this.dbgout) { this.res = "-- --------- Debug-Information: Parameter dbgout = " + this.dbgout + " ---------- " + this.linesep; } else { this.res = ""; } this.res += "-- Report-Definitionen nach "+this.ident+", exportiert " + aux.nowsvtime() + this.linesep; } else { this.res = ""; } } else { this.errcoll.collect(null,"invalid exportformat given, valid are: REPDEFSQL",{ query: this.query }); break proc; } if (this.query.dbgout) { this.dbgout = true; } else { this.dbgout = false; } } # # <>: get and format data for the text node (composed of 1 or more fragments, sorted by frag_index) itself # sql select * from CCTEXTFRAG where ident=::ident:: order by frag_index asc named_params ident result_varname noderes post_qexpression proc: { if ((!this.noderes) || (this.noderes.resulttype!="dbresult") || (this.noderes.getRowCount()<1)) { this.errcoll.collect(null,"no valid DB result for text node \""+this.ident+"\"", { noderes: this.noderes }); break proc; } this.res += this.renderNode(this.noderes,this.exportformat,{ linesep: this.linesep }); } # # <>: now get all children of this node (if there are any) and append them # sql select distinct ident,child_index from CCTEXTFRAG where parent=::ident:: order by child_index asc named_params ident result_varname childres post_qexpression proc: { if ((!this.childres) || (this.childres.resulttype!="dbresult") || (this.childres.getColumnCount()<1)) { this.errcoll.collect(null,"no valid DB result for text node children of text ident \""+this.ident+"\"", { childres: this.childres }); break proc; } this.childrencount = this.childres.getRowCount(); this.childnum = 0; } # # <>: if all children processed, then we're complete # proc_children_loop: if (this.childnum>=this.childrencount) goto proc_children_complete # # <>: process current child by recursively calling ourselves # pre_qexpression this.curchildident = this.childres.getCellValue(this.childnum,0); query.dataname exporttext query.textident @@curchildident@@ query.exportformat @@exportformat@@ query.toptextident @@toptextident@@ query.dbgout @@dbgout@@ result_varname curchildres post_qexpression proc: { if ((!this.curchildres) || (this.curchildres.resulttype!='plain') || (!this.curchildres.body)) { this.errcoll.collect(null,"no valid child node id=\""+this.curchildident+"\" rendering result", { curchildres: this.curchildres }); break proc; } this.res += this.curchildres.body; this.childnum++; } then_goto proc_children_loop # # <>: processing complete # proc_children_complete: qexpression if (this.ident==this.toptextident) { this.result = new aux.Result({ resulttype: "plain", body: "
" + this.res + "
" }); } else { if (!this.res) this.res += "-- ---- current result for text fragment: " + aux.objTxt(this.noderes) + "\" is nothing: \"" + this.res + "\", will be defaulted to empty SQL comment!" + this.linesep; this.result = new aux.Result({ resulttype: "plain", body: ( this.res || ( "--" + this.linesep )) }); } # # <>: done # end