#
#				ITSV GmbH
#	CCDB - Command and Control Database
#
#	FILE:			dquerymfile_notepadBackend.txt
#	DESCRIPTION:	DQUERY definition for DQUERY notepadBackend
#
@querytitle			Notepad Backend
@querydescription	alle für das Notepad benötigten Backend-Aktivitäten
@group				API
@attributenames		notepadname:string,cellid:string,action:string,data:string
@querytype			function
@function			seqtrans.seqtrans

~query.tsteps

#
# <<TSTEPNUM:0>>: determine action sequence
#
pre_qexpression
	proc: {
		this.copyqvars("action,notepadname,cellid,data");
		this.actlab = "action_"+this.action;
		if (!this.labels[this.actlab]) {
			this.errcoll.collect(null,	"Cannot execute Notepad backend action \""+this.action+"\","+
										" seqtrans label \""+this.actlab+"\" does not exist.",{ action: this.action, data: this.data });
			break proc;
		}
	}
goto	@@actlab@@

#
# ==============================================================================
#
# <<TSTEPNUM:1>>: action sql
#
action_sql:
pre_qexpression
	proc: {
		this.debug = false;
		this.aparams = {};
		this.data = aux.populate({	template:	this.data,
									data:		this.aparams,
									adata:		this,
									delimname:	"double_hashes",
									dbg:		this.debug
								});
		if (this.debug) logger.debug(this.phead("sql.populated")+".data=\""+this.data+"\".aparams: "+aux.objTxt(this.aprams));
		this.dataobject = aux.txtObjDecode(this.data);
		if (typeof(this.dataobject)=="string") {
			this.dataobject = { data: this.data };
		}
		this.dataobject.aparams = this.aparams;
		if (!this.dataobject.sql) this.dataobject.sql = this.dataobject.data;
		if (!this.dataobject.sql) {
			this.errcoll.collect(null,	"Cannot execute SQL, data contains no SQL", this.dataobject);
			break proc;
		}
		this.actsql = this.dataobject.sql;
		if (this.dataobject.aparams.cfgname) {
			this.tstep.cfgname = this.dataobject.aparams.cfgname;
		}
	}
sql				@@actsql@@
result_varname	sqlres
catch_errors	true
post_qexpression
	proc: {
		if (this.sqlres && this.sqlres.error) {
			this.result = new aux.Result({resulttype: 'plain', body: "Fehler beim Ausführen von SQL-Statement:<pre>"+aux.objTxt(this.sqlres.error)+"</pre>" });
			break proc;
		}
		if (this.sqlres && this.sqlres.resulttype && this.sqlres.resulttype=="dbresult") {
			if (this.debug) logger.debug(this.phead("SQL_DONE_DBRESULT")+".result: "+aux.objTxt(this.sqlres));
			this.result = this.sqlres;
		} else {
			if (this.debug) logger.debug(this.phead("SQL_DONE_NO_DBRESULT")+".result: "+aux.objTxt(this.sqlres));
			let rc = (	this.sqlres && 
						this.sqlres.resulttype && 
						this.sqlres.resulttype=='object' && 
						this.sqlres.resultobject && 
						this.sqlres.resultobject.hasOwnProperty("affectedRows"))?this.sqlres.resultobject.affectedRows:"FEHLER";
			if (rc=="FEHLER") {
				logger.error(this.phead("SQL_ERROR")+".error_result: "+aux.objTxt(this.sqlres));
				this.errcoll.collect(null,"Error not-wellformed result executing SQL statement",this.sqlres);
				break proc;
			}
			this.result = new aux.Result({resulttype: 'plain', body: "<pre>"+aux.objTxt(this.sqlres.resultobject)+"</pre>"});
		}
	}

#
# <<TSTEPNUM:2>>: action sql end
#
end

#
# ==============================================================================
#
# <<TSTEPNUM:3>>: action javascript
#
# pre_qexpression also provides hooks for the javascript fragment to access session-wide memory for this notepad in this.notepaddata
#
action_javascript:
pre_qexpression
	proc: {
		this.tstep.qexpression = this.data;
		this.printdata = new Array();
		this.print = function(what) {
			if (this.printdata.length<1) this.printdata.push("");
			if (typeof(what)!='string') what = String(what);
			if (what.indexOf("\n")<0) {
				this.printdata[this.printdata.length-1] += String(what);
			} else {
				let sa = what.split("\n");
				this.printdata[this.printdata.length-1] += sa[0];
				for (let si=1; si<sa.length; si++) {
					this.printdata.push(sa[si]);
				}
			}
		}
		this.println = function(what) {
			this.print(what);
			this.printdata.push("");
		}
		if (!this.session.notepads) this.session.notepads = {};
		if (!this.session.notepads[this.notepadname]) this.session.notepads[this.notepadname] = {};
		this.notepaddata = this.session.notepads[this.notepadname];
	}
qexpression
	this.result = new aux.Result({resulttype = "plain", body="No javascript got from request data: <pre>"+aux.objTxt(this.data)+"</pre>"});
catch_errors	true
result_varname	qres
post_qexpression
	proc: {
		if (this.qres && this.qres.error) {
			this.result = new aux.Result({resulttype: 'plain', body: "Fehler beim Ausführen von javascript:<pre>"+aux.objTxt(this.qres.error)+"</pre>" });
			break proc;
		}
		if (!this.qres  && this.printdata.length>0) {
			let phtml = "<code>";
			for (let li=0; li<this.printdata.length; li++) {
				phtml += "<p>"+this.printdata[li]+"</p>\n";
			}
			phtml += "</code>\n";
			this.qres = new aux.Result({resulttype: "plain", body: phtml});
		}			
		if (this.qres && this.qres.resulttype && this.qres.resulttype=="plain") {
			this.result = this.qres;
		} else if (this.qres && this.qres.resulttype && this.qres.resulttype=="dbresult") {
			this.result = this.qres;
		} else {
			/* logger.debug(this.phead("JS_DONE_NO_DBRESULT")+".result: "+aux.objTxt(this.qres)); */
			this.result = new aux.Result({resulttype: 'plain', body: "<pre>"+aux.objTxt(this.qres)+"</pre>"});
		}
	}

#
# <<TSTEPNUM:4>>: action javascript end
#
end	

#
# ==============================================================================
#
# <<TSTEPNUM:5>>: action query
#
action_query:
pre_qexpression
	proc: {	
		this.debug = true;
		this.aparams = {};
		this.data = aux.populate({	template:	this.data,
									data:		this.aparams,
									adata:		this,
									delimname:	"double_hashes",
									dbg:		this.debug
								});
		if (this.debug) logger.debug(this.phead("query.populated")+".data=\""+this.data+"\".aparams: "+aux.objTxt(this.aparams));
		this.qobject = aux.txtObjDecode(this.data);
		if (this.debug) {
			logger.debug(this.phead("query.txtDecode")+".qobject: "+aux.objTxt(this.qobject));
		}
		if (this.qobject.error) {
			this.errcoll.collect(this.qobject.error,"Error parsing query-object",this.data);
			break proc;
		}
		if (typeof(this.qobject)=="string") {
			this.qobject = { data: this.data };
		}
		if (!aux.objectIsEmpty(this.aparams)) aux.copyObject(this.qobject,this.aparams);
		this.tstep.query = aux.deepCopy(this.qobject);
	}
query.dataname		***notepadBackend.query.UNDEFINED***
catch_errors	true
result_varname	qres
post_qexpression
	proc: {
		if (this.qres && this.qres.error) {
			this.result = new aux.Result({resulttype: 'plain', body: "Fehler beim Ausführen von DQUERY:<pre>"+aux.objTxt(this.qres.error)+"</pre>" });
			break proc;
		}
		if (this.qres && this.qres.resulttype && this.qres.resulttype=="plain") {
			this.result = this.qres;
		} else if (this.qres && this.qres.resulttype && this.qres.resulttype=="dbresult") {
			this.result = this.qres;
		} else {
			/* logger.debug(this.phead("QUERY_DONE_NO_DBRESULT")+".result: "+aux.objTxt(this.qres)); */
			this.result = new aux.Result({resulttype: 'plain', body: "<pre>"+aux.objTxt(this.qres)+"</pre>"});
		}
	}

#
# <<TSTEPNUM:6>>: action query end
#
end	

#
# ==============================================================================
#
# <<TSTEPNUM:7>>: action save, check if already saved under this name
#
action_save:
sql				select type,ident,version,parent,child_index,frag_index from CCTEXTFRAG where type='CCDBNOTEPAD' and ident=::notepadname::
named_params	notepadname
result_varname	dbres	

#
# <<TSTEPNUM:8>>: determine if create or update
#
if (this.dbres.getRowCount()>0)
goto	action_save_update

#
# <<TSTEPNUM:9>>: action save create
#
pre_qexpression
	this.jsondata = JSON.stringify(this.data);
sql				insert into CCTEXTFRAG(type,ident,version,parent,child_index,frag_index,data)
				       values('CCDBNOTEPAD',::notepadname::,0,'CCDBNOTEPADS',0,0,::jsondata::)
named_params	notepadname,jsondata
result_varname	dbres
post_qexpression
	proc: {
		let rc = (this.dbres && this.dbres.resulttype && this.dbres.resulttype=='object' && this.dbres.resultobject && this.dbres.resultobject.affectedRows)?this.dbres.resultobject.affectedRows:"FEHLER";
		if (rc=="FEHLER") {
			this.errcoll.collect(null,"Error not-wellformed result saving notepad CCTEXTFRAG record",this.dbres);
			break proc;
		}
		this.result = new aux.Result({resulttype: 'plain', body: "Notepad \""+this.notepadname+"\" neu angelegt, "+rc+" Datensätze verändert"});
	}

#
# <<TSTEPNUM:10>>: action save create end
#
end

#
# <<TSTEPNUM:11>>: action save update
#
action_save_update:
pre_qexpression
	this.jsondata = JSON.stringify(this.data);
	this.version = this.dbres.getCellValue(0,2);
sql				update CCTEXTFRAG set version=::version::+1,data=::jsondata:: where type='CCDBNOTEPAD' and ident=::notepadname::
named_params	version,jsondata,notepadname
result_varname	dbres
post_qexpression
	proc: {
		let rc = (this.dbres && this.dbres.resulttype && this.dbres.resulttype=='object' && this.dbres.resultobject && this.dbres.resultobject.affectedRows)?this.dbres.resultobject.affectedRows:"FEHLER";
		if (rc=="FEHLER") {
			this.errcoll.collect(null,"Error not-wellformed result in updateing notepad CCTEXTFRAG record",this.dbres);
			break proc;
		}
		this.result = new aux.Result({resulttype: 'plain', body: "Notepad \""+this.notepadname+"\" geändert, "+rc+" Datensätze verändert"});
	}

#
# <<TSTEPNUM:12>>: action save update end
#
end

#
# ==============================================================================
#
# <<TSTEPNUM:13>>: action load -	load the notepad <notepadname> from the database
#								notpad <notepadname> is stored in CCTEXTFRAG with 
#									-	type	=	'CCDBNOTEPAD'
#									-	ident	=	<notepadname>
#
action_load:
sql			select  type,ident,version,parent,child_index,frag_index,data from CCTEXTFRAG where type='CCDBNOTEPAD' and ident=::notepadname::
named_params	notepadname
result_varname	dbres	
post_qexpression
	proc: {
		if (this.dbres.getRowCount()<1) {
			this.errcoll.collect(null,"Error reading notepad for name \""+this.notepadname+"\", no data returned");
			break proc;
		}
		this.result = new aux.Result({ resulttype: "transparent", res: aux.txtObjDecode(this.dbres.getCellValue(0,6)) });
	}

#
# <<TSTEPNUM:14>>: action load end
#
end	
