<commit_before>/*
* visualizer.js
* Created by: sethtoles
* Date created: 3/11/14
* Uses d3 to visualize qubits.
*/

var defaultQubit =  [{up: {prob: 1, phase: 0}, down: {prob: 0, phase: 0}}],
	qubits = d3.select("#qubitSVG")
		.attr("width", "100%")
		.attr("height", "100%");

function updateQubits(qubitStates) {
		// General settings
	var margin = .9,
		qubitScale = .9,
		animTime = 1000,
		// Environment info
		numQubits = qubitStates.length,
		svgWidth = parseInt(qubits.style("width")),
		svgHeight = parseInt(qubits.style("height")),
		containerMin = Math.min(svgWidth, svgHeight),
		dim = margin * containerMin,
		// Qubit properties
		qubitRadius = qubitScale * dim / 2,
		arrangeRadius = 0,
		yOffset = 0,
		rotateDeg = 360 / numQubits;

	if (numQubits > 1) {
		var theta = 2 * Math.PI / numQubits,
			p = qubitScale * Math.sin(theta / 2);
		if (numQubits % 2 === 0) {
			arrangeRadius = dim / (2 * (p + 1));
			qubitRadius = dim / 2 - arrangeRadius;
		} else {
			var phi = theta * (numQubits - 1) / 2;
			arrangeRadius = dim / (2 * p + Math.sqrt(2 * (1 - Math.cos(phi))));
			qubitRadius = arrangeRadius * p;
			yOffset = arrangeRadius * (1 - Math.cos(theta / 2));
		}
	}

	function qubitTransform(index, c, r, t, s) {
		var center = c || "translate(" + (svgWidth / 2) + ", " + ((svgHeight / 2) + yOffset / 2) + ")",
			rotate = r || "rotate(" + (rotateDeg * index) + ")",
			translate = t || "translate(0, -" + arrangeRadius + ")"
			straighten = s || "rotate(-" + (rotateDeg * index) + ")";

		return center + rotate + translate + straighten;
	}

	// --- QUBITS --- //
	var qubit = qubits.selectAll(".qubit").data(qubitStates);

	// Add qubits if necessary
	qubit.enter().append("g")
		.attr("class", "qubit")
		.attr("transform", function(d, i) { return qubitTransform(i, false, "", "", "") });

	// Remove qubits if necessary
	qubit.exit().transition()
		.duration(animTime)
		.attr("transform", "scale(0)")
		.remove();

	// Update qubit arrangement
	qubit.transition()
		.duration(animTime)
		.attr("transform", function(d, i) { return qubitTransform(i) });

	// --- QUBIT BACK --- //
	var qubitBack = qubit.selectAll(".qubit-back").data([qubitRadius]);

	// Add qubit-back if necessary
	qubitBack.enter().append("circle")
		.attr("class", "qubit-back")
		.attr("r", qubitRadius);

	// Update qubit-back
	qubitBack.transition()
		.duration(animTime)
		.attr("r", qubitRadius);

	// --- SUBSTATES --- //
	var substate = qubit.selectAll(".substate").data(function(d) { return [d.up, d.down] });

	// Add substates if necessary
	substate.enter().append("g")
		.attr("class", "substate")
		.attr("transform", "rotate(180)");

	// Update substates
	substate.transition()
		.duration(animTime)
		.attr("transform", function(d) { return "rotate(" + (180 + d.phase) + ")" });

	// --- PROB-RINGS --- //
	var probRing = substate.selectAll(".prob-ring").data(function(d, i) {
		return [{
			substate: (i % 2 === 0) ? "up" : "down",
			value: d.prob
		}];
	});

	// Add prob-rings if necessary
	probRing.enter().append("circle")
		.attr("class", function(d) { return "prob-ring " + d.substate; })
		.attr("r", function(d) {
			var radius = (d.substate === "up") ? (1 - d.value) * qubitRadius + 1 : d.value * qubitRadius - 1;
			return (radius < 0) ? 0 : radius;
		});

	// Update prob-ring size
	probRing.transition()
	  	.duration(animTime)
		.attr("r", function(d) {
			var radius = (d.substate === "up") ? (1 - d.value) * qubitRadius + 1 : d.value * qubitRadius - 1;
			return (radius < 0) ? 0 : radius;
		});

	// --- BARS --- //
	var bar = substate.selectAll(".bar").data(function(d, i) {
		return [{
			substate: (i % 2 === 0) ? "up" : "down",
			prob: d.prob,
			phase: d.phase
		}];
	});

	// Add bars if necessary
	bar.enter().append("rect")
		.attr("class", function(d) { return "bar " + d.substate; })
		.attr("width", 5)
		.attr("height", function(d) { return ((d.prob < 0) ? 0 : d.prob) * qubitRadius })
		.attr("x", - 2.5)
		.attr("y", - .5)
		.attr("transform", function(d) {
			return (d.substate === "up") ? "translate(0, " + ((1 - d.prob) * qubitRadius) + ")" : "";
		});;

	// Update bar attributes
	bar.transition()
	  	.duration(animTime)
		.attr("height", function(d) { return ((d.prob < 0) ? 0 : d.prob) * qubitRadius })
		.attr("transform", function(d) {
			return (d.substate === "up") ? "translate(0, " + ((1 - d.prob) * qubitRadius) + ")" : "";
		});
}
<commit_msg>Working fully with editor<commit_after>/*
* visualizer.js
* Created by: sethtoles
* Date created: 3/11/14
* Uses d3 to visualize qubits.
*/

var defaultQubit =  [{up: {prob: 1, phase: 0}, down: {prob: 0, phase: 0}}],
	qubits = d3.select("#qubitSVG")
		.attr("width", "100%")
		.attr("height", "100%");

function updateQubits(qubitStates) {
		// General settings
	var margin = .9,
		qubitScale = .75,
		animTime = 800,
		// Environment info
		numQubits = qubitStates.length,
		svgWidth = parseInt(qubits.style("width")),
		svgHeight = parseInt(qubits.style("height")),
		containerMin = Math.min(svgWidth, svgHeight),
		dim = margin * containerMin,
		// Qubit properties
		qubitRadius = qubitScale * dim / 2,
		arrangeRadius = 0,
		yOffset = 0;

	if (numQubits > 1) {
		var theta = 2 * Math.PI / numQubits,
			p = qubitScale * Math.sin(theta / 2);
		if (numQubits % 2 === 0) {
			arrangeRadius = dim / (2 * (p + 1));
			qubitRadius = dim / 2 - arrangeRadius;
		} else {
			var phi = theta * (numQubits - 1) / 2;
			arrangeRadius = dim / (2 * p + Math.sqrt(2 * (1 - Math.cos(phi))));
			qubitRadius = arrangeRadius * p;
			yOffset = arrangeRadius * (1 - Math.cos(theta / 2));
		}
	}

	function positionQubit(index, remove) {
		var realNumQubits = (remove) ? index + 1 : numQubits,
			rotateDeg = 360 / realNumQubits,
			center = "translate(" + (svgWidth / 2) + ", " + ((svgHeight / 2) + yOffset / 2) + ")",
			rotate = "rotate(" + (rotateDeg * index) + ")",
			translate = "translate(0, -" + arrangeRadius + ")"
			straighten = "rotate(-" + (rotateDeg * index) + ")";

		return center + rotate + translate + straighten;
	}

	// --- QUBITS --- //
	var qubit = qubits.selectAll(".qubit").data(qubitStates);

	// Add qubits if necessary
	qubit.enter().append("g")
		.attr("class", "qubit")
		.attr("transform", function(d, i) { return positionQubit(i) + "scale(0)"})
	  .append("circle")
		.attr("class", "qubit-back");

	// Update qubit arrangement
	qubit.transition()
		.duration(animTime)
		.attr("transform", function(d, i) { return positionQubit(i) + "scale(1)" });

	// Update qubit-back
	qubit.select(".qubit-back").transition()
		.duration(animTime)
		.attr("r", qubitRadius);

	// Remove qubits if necessary
	qubit.exit().transition()
		.duration(animTime / 2)
		.attr("transform", function(d, i) { return positionQubit(i, true) + "scale(0)" })
		.remove();

	// --- SUBSTATES --- //
	var substate = qubit.selectAll(".substate").data(function(d) { return [d.up, d.down] });

	// Add substates if necessary
	substate.enter().append("g")
		.attr("class", "substate")
		.attr("transform", "rotate(180)");

	// Update substates
	substate.transition()
		.duration(animTime)
		.attr("transform", function(d) { return "rotate(" + (180 + d.phase) + ")" });

	// --- PROB-RINGS --- //
	var probRing = substate.selectAll(".prob-ring").data(function(d, i) {
		return [{
			substate: (i % 2 === 0) ? "up" : "down",
			value: d.prob
		}];
	});

	// Add prob-rings if necessary
	probRing.enter().append("circle")
		.attr("class", function(d) { return "prob-ring " + d.substate; })
		.attr("r", function(d) {
			var radius = (d.substate === "up") ? (1 - d.value) * qubitRadius + 1 : d.value * qubitRadius - 1;
			return (radius < 0) ? 0 : radius;
		});

	// Update prob-ring size
	probRing.transition()
	  	.duration(animTime)
		.attr("r", function(d) {
			var radius = (d.substate === "up") ? (1 - d.value) * qubitRadius + 1 : d.value * qubitRadius - 1;
			return (radius < 0) ? 0 : radius;
		});

	// --- BARS --- //
	var bar = substate.selectAll(".bar").data(function(d, i) {
		return [{
			substate: (i % 2 === 0) ? "up" : "down",
			prob: d.prob,
			phase: d.phase
		}];
	});

	// Add bars if necessary
	bar.enter().append("rect")
		.attr("class", function(d) { return "bar " + d.substate; })
		.attr("width", 5)
		.attr("height", function(d) { return ((d.prob < 0) ? 0 : d.prob) * qubitRadius })
		.attr("x", - 2.5)
		.attr("y", - .5)
		.attr("transform", function(d) {
			return (d.substate === "up") ? "translate(0, " + ((1 - d.prob) * qubitRadius) + ")" : "";
		});;

	// Update bar attributes
	bar.transition()
	  	.duration(animTime)
		.attr("height", function(d) { return ((d.prob < 0) ? 0 : d.prob) * qubitRadius })
		.attr("transform", function(d) {
			return (d.substate === "up") ? "translate(0, " + ((1 - d.prob) * qubitRadius) + ")" : "";
		});
}
<|endoftext|>


<commit_before>// @flow

const Promise = require("bluebird");
const OpenShiftClient = require('openshift-client');
const sleep = require("es7-sleep");
const R = require('ramda');
const { logger } = require('@lagoon/commons/src/local-logging');
const {
  getOpenShiftInfoForProject,
  getEnvironmentByName,
  updateEnvironment,
  getDeploymentByRemoteId,
  getDeploymentByName,
  updateDeployment,
  updateProject,
  setEnvironmentServices,
} = require('@lagoon/commons/src/api');

const { sendToLagoonLogs, initSendToLagoonLogs } = require('@lagoon/commons/src/logs');
const { consumeTaskMonitor, initSendToLagoonTasks } = require('@lagoon/commons/src/tasks');

class BuildNotCompletedYet extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'BuildNotCompletedYet';
  }
}

initSendToLagoonLogs();
initSendToLagoonTasks();

const messageConsumer = async msg => {
  const {
    buildName,
    projectName,
    openshiftProject,
    branchName,
    sha
  } = JSON.parse(msg.content.toString())

  logger.verbose(`Received BuildDeployOpenshift monitoring task for project: ${projectName}, buildName: ${buildName}, openshiftProject: ${openshiftProject}, branch: ${branchName}, sha: ${sha}`);
  const projectResult = await getOpenShiftInfoForProject(projectName);
  const project = projectResult.project

  const environmentResult = await getEnvironmentByName(branchName, project.id)
  const environment = environmentResult.environmentByName

  const deploymentResult = await getDeploymentByName(openshiftProject, buildName);
  const deployment = deploymentResult.environment.deployments[0];

  try {
    var gitSha = sha
    var openshiftConsole = project.openshift.consoleUrl.replace(/\/$/, "");
    var openshiftToken = project.openshift.token || ""
  } catch(error) {
    logger.warn(`Error while loading information for project ${projectName}: ${error}`)
    throw(error)
  }

  // OpenShift API object
  const openshift = new OpenShiftClient.OApi({
    url: openshiftConsole,
    insecureSkipTlsVerify: true,
    auth: {
      bearer: openshiftToken
    },
  });

  // Kubernetes API Object - needed as some API calls are done to the Kubernetes API part of OpenShift and
  // the OpenShift API does not support them.
  const kubernetes = new OpenShiftClient.Core({
    url: openshiftConsole,
    insecureSkipTlsVerify: true,
    auth: {
      bearer: openshiftToken
    },
  });

  // kubernetes-client does not know about the OpenShift Resources, let's teach it.
  openshift.ns.addResource('builds');
  openshift.ns.addResource('deploymentconfigs');

  let projectStatus = {}
  try {
    const projectsGet = Promise.promisify(openshift.projects(openshiftProject).get, { context: openshift.projects(openshiftProject) })
    projectStatus = await projectsGet()
  } catch (err) {
    // a non existing project also throws an error, we check if it's a 404, means it does not exist, so we create it.
    if (err.code == 404) {
      logger.error(`Project ${openshiftProject} does not exist, bailing`)
      return
    } else {
      logger.error(err)
      throw new Error
    }
  }

  try {
    const buildsGet = Promise.promisify(openshift.ns(openshiftProject).builds(buildName).get, { context: openshift.ns(openshiftProject).builds(buildName) })
    buildstatus = await buildsGet()
  } catch (err) {
    if (err.code == 404) {
      logger.error(`Build ${buildName} does not exist, bailing`)
      return
    } else {
      logger.error(err)
      throw new Error
    }
  }

  const buildPhase = buildstatus.status.phase.toLowerCase();
  const buildsLogGet = Promise.promisify(openshift.ns(openshiftProject).builds(`${buildName}/log`).get, { context: openshift.ns(openshiftProject).builds(`${buildName}/log`) })
  const routesGet = Promise.promisify(openshift.ns(openshiftProject).routes.get, { context: openshift.ns(openshiftProject).routes })

  try {
    const deployment = await getDeploymentByRemoteId(buildstatus.metadata.uid);
    if (!deployment.deploymentByRemoteId) {
      throw new Error(`No deployment found with remote id ${buildstatus.metadata.uid}`);
    }

    const convertDateFormat = R.init;
    const dateOrNull = R.unless(R.isNil, convertDateFormat);

    await updateDeployment(deployment.deploymentByRemoteId.id, {
      status: buildstatus.status.phase.toUpperCase(),
      created: convertDateFormat(buildstatus.metadata.creationTimestamp),
      started: dateOrNull(buildstatus.status.startTimestamp),
      completed: dateOrNull(buildstatus.status.completionTimestamp),
    });
  } catch (error) {
    logger.error(`Could not update deployment ${projectName} ${buildName}. Message: ${error}`);
  }

  const meta = JSON.parse(msg.content.toString())
  const logLink = deployment.uiLink;
  let logMessage = ''
  if (sha) {
    meta.shortSha = sha.substring(0, 7)
    logMessage = `\`${branchName}\` (${sha.substring(0, 7)})`
  } else {
    logMessage = `\`${branchName}\``
  }
  switch (buildPhase) {
    case "new":
    case "pending":
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` not yet started`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` not yet started`)
      break;

    case "running":
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` running`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` running`)
      break;

    case "cancelled":
    case "error":
      sendToLagoonLogs('warn', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` cancelled. <${logLink}|Logs>`
      )
      break;

    case "failed":
      sendToLagoonLogs('error', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` failed. <${logLink}|Logs>`
      )
      break;

    case "complete":
      try {
        const buildLog = await buildsLogGet()
        await saveBuildLog(buildName, projectName, branchName, buildLog, buildstatus)
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while getting and sending to lagoon-logs, Error: ${err}.`)
      }

      try {
        const configMapGet = Promise.promisify(kubernetes.ns(openshiftProject).configmaps('lagoon-env').get, { context: kubernetes.ns(openshiftProject).configmaps('lagoon-env') })
        configMap = await configMapGet()
      } catch (err) {
        if (err.code == 404) {
          logger.error(`configmap lagoon-env does not exist, continuing without routes information`)
        } else {
          logger.error(err)
          throw new Error
        }
      }

      const route = configMap.data.LAGOON_ROUTE
      const routes = configMap.data.LAGOON_ROUTES.split(',').filter(e => e !== route);
      meta.route = route
      meta.routes = routes
      meta.logLink = loglink
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` complete. <${logLink}|Logs> \n ${route}\n ${routes.join("\n")}`
      )

      try {
        const updateEnvironmentResult = await updateEnvironment(
          environment.id,
          `{
            route: "${configMap.data.LAGOON_ROUTE}",
            routes: "${configMap.data.LAGOON_ROUTES}",
            monitoringUrls: "${configMap.data.LAGOON_MONITORING_URLS}",
            project: ${project.id}
          }`)
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while updating routes in API, Error: ${err}. Continuing without update`)
      }

      //update the active/standby routes in the api
      try {
        if (project.productionEnvironment == environment.name) {
          const updateProjectResult = await updateProject(project.id, {
            productionRoutes: configMap.data.LAGOON_ACTIVE_ROUTES,
          });
        } else if (project.standbyProductionEnvironment == environment.name){
          const updateProjectResult = await updateProject(project.id, {
            standbyRoutes: configMap.data.LAGOON_STANDBY_ROUTES,
          });
        }
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while updating active/standby routes in API, Error: ${err}. Continuing without update`)
      }

      // Tell api what services are running in this environment
      try {
        // Get pod template from existing service
        const deploymentConfigsGet = Promise.promisify(
          openshift.ns(openshiftProject).deploymentconfigs.get, { context: openshift.ns(openshiftProject).deploymentconfigs }
        );
        const deploymentConfigs = await deploymentConfigsGet();

        const serviceNames = deploymentConfigs.items.reduce(
          (names, deploymentConfig) => [
            ...names,
            ...deploymentConfig.spec.template.spec.containers.reduce(
              (names, container) => [
                ...names,
                container.name
              ],
              []
            )
          ],
          []
        );

        await setEnvironmentServices(environment.id, serviceNames);
      } catch (err) {
        logger.error(`${openshiftProject} ${buildName}: Error while updating environment services in API, Error: ${err}`)
      }
      break;

    default:
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` phase ${buildPhase}`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` phase ${buildPhase}`)
      break;
  }

}

const saveBuildLog = async(buildName, projectName, branchName, buildLog, buildStatus) => {
  const meta = {
    buildName,
    branchName,
    buildPhase: buildStatus.status.phase.toLowerCase(),
    remoteId: buildStatus.metadata.uid
  };
  sendToLagoonLogs('info', projectName, "", `build-logs:builddeploy-openshift:${buildName}`, meta,
    buildLog
  );
}

const deathHandler = async (msg, lastError) => {
  const {
    buildName,
    projectName,
    openshiftProject,
    branchName,
    sha
  } = JSON.parse(msg.content.toString())

  let logMessage = ''
  if (sha) {
    logMessage = `\`${branchName}\` (${sha.substring(0, 7)})`
  } else {
    logMessage = `\`${branchName}\``
  }

  sendToLagoonLogs('error', projectName, "", "task:builddeploy-openshift:error",  {},
`*[${projectName}]* ${logMessage} Build \`${buildName}\` ERROR:
\`\`\`
${lastError}
\`\`\``
  )

}

consumeTaskMonitor('builddeploy-openshift', messageConsumer, deathHandler)
<commit_msg>dont populate the loglink in meta<commit_after>// @flow

const Promise = require("bluebird");
const OpenShiftClient = require('openshift-client');
const sleep = require("es7-sleep");
const R = require('ramda');
const { logger } = require('@lagoon/commons/src/local-logging');
const {
  getOpenShiftInfoForProject,
  getEnvironmentByName,
  updateEnvironment,
  getDeploymentByRemoteId,
  getDeploymentByName,
  updateDeployment,
  updateProject,
  setEnvironmentServices,
} = require('@lagoon/commons/src/api');

const { sendToLagoonLogs, initSendToLagoonLogs } = require('@lagoon/commons/src/logs');
const { consumeTaskMonitor, initSendToLagoonTasks } = require('@lagoon/commons/src/tasks');

class BuildNotCompletedYet extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'BuildNotCompletedYet';
  }
}

initSendToLagoonLogs();
initSendToLagoonTasks();

const messageConsumer = async msg => {
  const {
    buildName,
    projectName,
    openshiftProject,
    branchName,
    sha
  } = JSON.parse(msg.content.toString())

  logger.verbose(`Received BuildDeployOpenshift monitoring task for project: ${projectName}, buildName: ${buildName}, openshiftProject: ${openshiftProject}, branch: ${branchName}, sha: ${sha}`);
  const projectResult = await getOpenShiftInfoForProject(projectName);
  const project = projectResult.project

  const environmentResult = await getEnvironmentByName(branchName, project.id)
  const environment = environmentResult.environmentByName

  const deploymentResult = await getDeploymentByName(openshiftProject, buildName);
  const deployment = deploymentResult.environment.deployments[0];

  try {
    var gitSha = sha
    var openshiftConsole = project.openshift.consoleUrl.replace(/\/$/, "");
    var openshiftToken = project.openshift.token || ""
  } catch(error) {
    logger.warn(`Error while loading information for project ${projectName}: ${error}`)
    throw(error)
  }

  // OpenShift API object
  const openshift = new OpenShiftClient.OApi({
    url: openshiftConsole,
    insecureSkipTlsVerify: true,
    auth: {
      bearer: openshiftToken
    },
  });

  // Kubernetes API Object - needed as some API calls are done to the Kubernetes API part of OpenShift and
  // the OpenShift API does not support them.
  const kubernetes = new OpenShiftClient.Core({
    url: openshiftConsole,
    insecureSkipTlsVerify: true,
    auth: {
      bearer: openshiftToken
    },
  });

  // kubernetes-client does not know about the OpenShift Resources, let's teach it.
  openshift.ns.addResource('builds');
  openshift.ns.addResource('deploymentconfigs');

  let projectStatus = {}
  try {
    const projectsGet = Promise.promisify(openshift.projects(openshiftProject).get, { context: openshift.projects(openshiftProject) })
    projectStatus = await projectsGet()
  } catch (err) {
    // a non existing project also throws an error, we check if it's a 404, means it does not exist, so we create it.
    if (err.code == 404) {
      logger.error(`Project ${openshiftProject} does not exist, bailing`)
      return
    } else {
      logger.error(err)
      throw new Error
    }
  }

  try {
    const buildsGet = Promise.promisify(openshift.ns(openshiftProject).builds(buildName).get, { context: openshift.ns(openshiftProject).builds(buildName) })
    buildstatus = await buildsGet()
  } catch (err) {
    if (err.code == 404) {
      logger.error(`Build ${buildName} does not exist, bailing`)
      return
    } else {
      logger.error(err)
      throw new Error
    }
  }

  const buildPhase = buildstatus.status.phase.toLowerCase();
  const buildsLogGet = Promise.promisify(openshift.ns(openshiftProject).builds(`${buildName}/log`).get, { context: openshift.ns(openshiftProject).builds(`${buildName}/log`) })
  const routesGet = Promise.promisify(openshift.ns(openshiftProject).routes.get, { context: openshift.ns(openshiftProject).routes })

  try {
    const deployment = await getDeploymentByRemoteId(buildstatus.metadata.uid);
    if (!deployment.deploymentByRemoteId) {
      throw new Error(`No deployment found with remote id ${buildstatus.metadata.uid}`);
    }

    const convertDateFormat = R.init;
    const dateOrNull = R.unless(R.isNil, convertDateFormat);

    await updateDeployment(deployment.deploymentByRemoteId.id, {
      status: buildstatus.status.phase.toUpperCase(),
      created: convertDateFormat(buildstatus.metadata.creationTimestamp),
      started: dateOrNull(buildstatus.status.startTimestamp),
      completed: dateOrNull(buildstatus.status.completionTimestamp),
    });
  } catch (error) {
    logger.error(`Could not update deployment ${projectName} ${buildName}. Message: ${error}`);
  }

  const meta = JSON.parse(msg.content.toString())
  const logLink = deployment.uiLink;
  let logMessage = ''
  if (sha) {
    meta.shortSha = sha.substring(0, 7)
    logMessage = `\`${branchName}\` (${sha.substring(0, 7)})`
  } else {
    logMessage = `\`${branchName}\``
  }
  switch (buildPhase) {
    case "new":
    case "pending":
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` not yet started`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` not yet started`)
      break;

    case "running":
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` running`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` running`)
      break;

    case "cancelled":
    case "error":
      sendToLagoonLogs('warn', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` cancelled. <${logLink}|Logs>`
      )
      break;

    case "failed":
      sendToLagoonLogs('error', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` failed. <${logLink}|Logs>`
      )
      break;

    case "complete":
      try {
        const buildLog = await buildsLogGet()
        await saveBuildLog(buildName, projectName, branchName, buildLog, buildstatus)
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while getting and sending to lagoon-logs, Error: ${err}.`)
      }

      try {
        const configMapGet = Promise.promisify(kubernetes.ns(openshiftProject).configmaps('lagoon-env').get, { context: kubernetes.ns(openshiftProject).configmaps('lagoon-env') })
        configMap = await configMapGet()
      } catch (err) {
        if (err.code == 404) {
          logger.error(`configmap lagoon-env does not exist, continuing without routes information`)
        } else {
          logger.error(err)
          throw new Error
        }
      }

      const route = configMap.data.LAGOON_ROUTE
      const routes = configMap.data.LAGOON_ROUTES.split(',').filter(e => e !== route);
      meta.route = route
      meta.routes = routes
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` complete. <${logLink}|Logs> \n ${route}\n ${routes.join("\n")}`
      )

      try {
        const updateEnvironmentResult = await updateEnvironment(
          environment.id,
          `{
            route: "${configMap.data.LAGOON_ROUTE}",
            routes: "${configMap.data.LAGOON_ROUTES}",
            monitoringUrls: "${configMap.data.LAGOON_MONITORING_URLS}",
            project: ${project.id}
          }`)
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while updating routes in API, Error: ${err}. Continuing without update`)
      }

      //update the active/standby routes in the api
      try {
        if (project.productionEnvironment == environment.name) {
          const updateProjectResult = await updateProject(project.id, {
            productionRoutes: configMap.data.LAGOON_ACTIVE_ROUTES,
          });
        } else if (project.standbyProductionEnvironment == environment.name){
          const updateProjectResult = await updateProject(project.id, {
            standbyRoutes: configMap.data.LAGOON_STANDBY_ROUTES,
          });
        }
      } catch (err) {
        logger.warn(`${openshiftProject} ${buildName}: Error while updating active/standby routes in API, Error: ${err}. Continuing without update`)
      }

      // Tell api what services are running in this environment
      try {
        // Get pod template from existing service
        const deploymentConfigsGet = Promise.promisify(
          openshift.ns(openshiftProject).deploymentconfigs.get, { context: openshift.ns(openshiftProject).deploymentconfigs }
        );
        const deploymentConfigs = await deploymentConfigsGet();

        const serviceNames = deploymentConfigs.items.reduce(
          (names, deploymentConfig) => [
            ...names,
            ...deploymentConfig.spec.template.spec.containers.reduce(
              (names, container) => [
                ...names,
                container.name
              ],
              []
            )
          ],
          []
        );

        await setEnvironmentServices(environment.id, serviceNames);
      } catch (err) {
        logger.error(`${openshiftProject} ${buildName}: Error while updating environment services in API, Error: ${err}`)
      }
      break;

    default:
      sendToLagoonLogs('info', projectName, "", `task:builddeploy-openshift:${buildPhase}`, meta,
        `*[${projectName}]* ${logMessage} Build \`${buildName}\` phase ${buildPhase}`
      )
      throw new BuildNotCompletedYet(`*[${projectName}]* ${logMessage} Build \`${buildName}\` phase ${buildPhase}`)
      break;
  }

}

const saveBuildLog = async(buildName, projectName, branchName, buildLog, buildStatus) => {
  const meta = {
    buildName,
    branchName,
    buildPhase: buildStatus.status.phase.toLowerCase(),
    remoteId: buildStatus.metadata.uid
  };
  sendToLagoonLogs('info', projectName, "", `build-logs:builddeploy-openshift:${buildName}`, meta,
    buildLog
  );
}

const deathHandler = async (msg, lastError) => {
  const {
    buildName,
    projectName,
    openshiftProject,
    branchName,
    sha
  } = JSON.parse(msg.content.toString())

  let logMessage = ''
  if (sha) {
    logMessage = `\`${branchName}\` (${sha.substring(0, 7)})`
  } else {
    logMessage = `\`${branchName}\``
  }

  sendToLagoonLogs('error', projectName, "", "task:builddeploy-openshift:error",  {},
`*[${projectName}]* ${logMessage} Build \`${buildName}\` ERROR:
\`\`\`
${lastError}
\`\`\``
  )

}

consumeTaskMonitor('builddeploy-openshift', messageConsumer, deathHandler)
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var spawn = require('child_process').spawn;

/**
 * The default path to the CINEMA 4D Application.
 */
var cinema4d_path = '/Applications/MAXON/CINEMA\ 4D R14/CINEMA\ 4D.app/Contents/MacOS/CINEMA\ 4D';

/**
 * Set the path to the CINEMA 4D Application.
 */
exports.setApplicationPath = function(path) {
  cinema4d_path = path;
}

/**
 * This is the main render function.
 */
exports.render = function(d) {
  // Print the d object. used for development and debugging
  console.log(d);

  // Check if a filepath is set. if no filepath is set, we cannot render...
  if (d.filepath === undefined) {
    log(d, 'No CINEMA 4D file to render.');
  }
  // Call the render...
  else {
    // This is the cli options array we need to execute with the spawn function.
    var tmpOptionsArray = [];
    tmpOptionsArray.push('-nogui');
    tmpOptionsArray.push('-render');
    tmpOptionsArray.push(d.filepath);

    // Check the different options...
    if (d.oimage !== undefined) {
      tmpOptionsArray.push('-oimage');
      tmpOptionsArray.push(d.oimage);
    };
    if (d.omultipass !== undefined) {
      tmpOptionsArray.push('-omultipass');
      tmpOptionsArray.push(d.omultipass);
    };
    if (d.oformat !== undefined) {
      tmpOptionsArray.push('-oformat');
      tmpOptionsArray.push(d.oformat);
    };
    if (d.threads !== undefined) {
      tmpOptionsArray.push('-threads');
      tmpOptionsArray.push(d.threads);
    };

    //log(d, tmpOptionsArray);

    // Execute the CINEMA 4D commandline interface.
    var c4dRender = spawn(cinema4d_path, tmpOptionsArray);
    c4dRender.stdout.on('data', function(data) {
      //console.log('VERSION: '+utils.getVersionFromStdout(data.toString()) );
      log(d, data.toString());
    });
    c4dRender.stderr.on('data', function(data) {
      log(d, 'Error: '+data.toString());
    });
    c4dRender.on('close', function(code) {
      //log(d, 'Closed with code: '+code);
    });
  }
}

/**
 * Log some data if the silent mode is not defined.
 *
 * @param d The data object.
 * @parma s The string we want to print out.
 */
function log(d, s) {
  if(d.silent === undefined) {
    console.log(s);
  }
}
<commit_msg>src/index.js added some api comments<commit_after>/**
 * Module dependencies.
 */
var spawn = require('child_process').spawn;

/**
 * The default path to the CINEMA 4D Application.
 *
 * @api private
 */
var cinema4d_path = '/Applications/MAXON/CINEMA\ 4D R14/CINEMA\ 4D.app/Contents/MacOS/CINEMA\ 4D';

/**
 * Set the path to the CINEMA 4D Application.
 *
 * @param {String} path
 * @api public
 */
exports.setApplicationPath = function(path) {
  cinema4d_path = path;
}

/**
 * This is the main render function.
 *
 * @api public
 */
exports.render = function(d) {
  // Print the d object. used for development and debugging
  console.log(d);

  // Check if a filepath is set. if no filepath is set, we cannot render...
  if (d.filepath === undefined) {
    log(d, 'No CINEMA 4D file to render.');
  }
  // Call the render...
  else {
    // This is the cli options array we need to execute with the spawn function.
    var tmpOptionsArray = [];
    tmpOptionsArray.push('-nogui');
    tmpOptionsArray.push('-render');
    tmpOptionsArray.push(d.filepath);

    // Check the different options...
    if (d.oimage !== undefined) {
      tmpOptionsArray.push('-oimage');
      tmpOptionsArray.push(d.oimage);
    };
    if (d.omultipass !== undefined) {
      tmpOptionsArray.push('-omultipass');
      tmpOptionsArray.push(d.omultipass);
    };
    if (d.oformat !== undefined) {
      tmpOptionsArray.push('-oformat');
      tmpOptionsArray.push(d.oformat);
    };
    if (d.threads !== undefined) {
      tmpOptionsArray.push('-threads');
      tmpOptionsArray.push(d.threads);
    };

    //log(d, tmpOptionsArray);

    // Execute the CINEMA 4D commandline interface.
    var c4dRender = spawn(cinema4d_path, tmpOptionsArray);
    c4dRender.stdout.on('data', function(data) {
      //console.log('VERSION: '+utils.getVersionFromStdout(data.toString()) );
      log(d, data.toString());
    });
    c4dRender.stderr.on('data', function(data) {
      log(d, 'Error: '+data.toString());
    });
    c4dRender.on('close', function(code) {
      //log(d, 'Closed with code: '+code);
    });
  }
}

/**
 * Log some data if the silent mode is not defined.
 *
 * @param d The data object.
 * @parma s The string we want to print out.
 * @api private
 */
function log(d, s) {
  if(d.silent === undefined) {
    console.log(s);
  }
}
<|endoftext|>


<commit_before>export { Plump } from './plump';
export { Model, $self, $all } from './model';
export { Storage } from './storage/storage';
export { MemoryStore } from './storage/memory';
export { KeyValueStore } from './storage/keyValueStore';
export { Relationship } from './relationship';
export { testSuite } from './test/storageTests';
export { TestType } from './test/testType';

// export {
//   Plump,
//   Model,
//   Storage,
//   MemoryStore,
//   KeyValueStore,
//   Relationship,
//   testSuite,
//   TestType,
//   $self,
//   $all,
// };
<commit_msg>removing test dep from index<commit_after>export { Plump } from './plump';
export { Model, $self, $all } from './model';
export { Storage } from './storage/storage';
export { MemoryStore } from './storage/memory';
export { KeyValueStore } from './storage/keyValueStore';
export { Relationship } from './relationship';
// export { testSuite } from './test/storageTests';
// export { TestType } from './test/testType';

// export {
//   Plump,
//   Model,
//   Storage,
//   MemoryStore,
//   KeyValueStore,
//   Relationship,
//   testSuite,
//   TestType,
//   $self,
//   $all,
// };
<|endoftext|>


<commit_before>Lizard.Views.WorkspaceItem = Backbone.Marionette.ItemView.extend({
  template: '#workspaceitem-template',
  tagName: 'li',
  className: 'drawer-item',
  initialize: function () {
    this.model.set('id', this.model.get('url'));
    this.model.bind('change', this.reRender, this);
  },
  reRender: function(){
    if (!this.model.hasChanged('opacity')) {
      this.render();
    }
  },
  onBeforeRender: function () {
    this.el.setAttribute("id", this.model.attributes.id);
  },
  onRender: function() {
    var that = this;
    debugger
    that.$el.find('.opacity-slider').slider({
        value: that.model.get('opacity'),
        min: 0,
        max: 100,
        range: "min",
        step: 1,
        create: function( event, ui ) {
          //that.model.unbind('change:opacity'); // This prevents the item from re-rendering...
        },
        slide: function( event, ui ) {
          //that.model.set('opacity', ui.value);
        },
        stop: function( event, ui ) {
          that.model.set('opacity', ui.value);
          $('.top-right').notify({
            message: {
              text: 'Transparantie van kaartlaag "' + that.model.get('display_name') + '" is nu ' + ui.value + '%'
            }}).show();
        }
    });
  },
  events: {
    'click .layer-item .indicator': 'toggleVisibility',
    'click .layer-item .content': 'select',
    'click .layer-item .toggle-layer-configuration': 'toggleLayerConfiguration',
    'click .layer-item .btn-delete-layer': 'removeLayer'
  },
  removeLayer: function(e) {
    // The collection belonging to this model, is not the same
    // as the workspace it is in.
    this.model.trigger('removeItem', this.model);
  },
  toggleLayerConfiguration: function() {
    $(this.el).find('.layer-configuration').toggle('fast');
    $(this.el).find('.toggle-layer-configuration i').toggleClass('chevron-closed chevron-open');
  },
  toggleVisibility: function () {
    if(this.model.attributes.visibility) {
      this.model.set({ visibility: false });
    } else {
      this.model.set({ visibility: true });
    }
  },
  select: function(e) {
    if(this.model.get('selected') === false) {
      this.model.collection.each(function(workspaceItem) {
        workspaceItem.set('selected', false);
      });
      this.model.set('selected', true);
      //this.model.trigger('select_layer', this.model);
    }
  }
});

Lizard.Views.ActiveWorkspace = Backbone.Marionette.CollectionView.extend({
  collection: new Lizard.Collections.Layer(), //layerCollection,
  tagName: 'ol',
  className: 'ui-sortable drawer-group wms_sources',
  itemView: Lizard.Views.WorkspaceItem,
  emptyView: Marionette.ItemView.extend({
    template: "#empty-workspace-list-message"
  }),
  events: {
    drop: 'drop'
  },
  initialize: function() {
    this.collection.on('reset', this.render, this);
    this.collection.on('removeItem', this.removeItem, this);
  },
  _initialEvents: function(){
    //this.collection.on("removeItems", this.onItemRemoveds, this);
  },
  drop: function(event, args) {
    debugger;
    this.collection.move(args.item, args.index);
    this.updateOrderFieldOfItems();
    //args.item.set({order: args.index});
    //args.item.attributes.layer.leafletLayer.setZIndex(100 - args.index);
  },
  updateOrderFieldOfItems: function() {
    index=0;
    this.collection.each(function(workspaceItem) {
      workspaceItem.set('order',index);
      index = index + 1;
    });
  },
  setWorkspace: function(workspace) {
    this.model = workspace;
    this.collection.reset(workspace.get('workspaceitems').models);
  },
  removeItem: function(model) {
    this.collection.remove(model);
    this.render();
  },
  onShow: function () {
    var that = this;
    $('.drawer-group').sortable({
      stop: function(event, ui) {
        var item = that.collection.get(ui.item.attr('id'));
        ui.item.trigger('drop', {
          item: item,
          index: ui.item.index()
        });
      }
    });
    $('.drawer-group').disableSelection();
  },
  onClose: function(){
    console.log('closing', this);
  },
  getCollection: function() {
    return this.collection;
  }
});

<commit_msg>fixed some unneeded re-render issues for active workspace<commit_after>Lizard.Views.WorkspaceItem = Backbone.Marionette.ItemView.extend({
  template: '#workspaceitem-template',
  tagName: 'li',
  className: 'drawer-item',
  initialize: function () {
    this.model.set('id', this.model.get('url'));
    this.model.bind('change:selected change:visibility', this.reRender, this);
  },
  reRender: function(){
    this.render();
  },
  onBeforeRender: function () {
    this.el.setAttribute("id", this.model.attributes.id);
  },
  onRender: function() {
    var that = this;
    that.$el.find('.opacity-slider').slider({
        value: that.model.get('opacity'),
        min: 0,
        max: 100,
        range: "min",
        step: 1,
        create: function( event, ui ) {
          //that.model.unbind('change:opacity'); // This prevents the item from re-rendering...
        },
        slide: function( event, ui ) {
          //that.model.set('opacity', ui.value);
        },
        stop: function( event, ui ) {
          that.model.set('opacity', ui.value);
          $('.top-right').notify({
            message: {
              text: 'Transparantie van kaartlaag "' + that.model.get('display_name') + '" is nu ' + ui.value + '%'
            }}).show();
        }
    });
  },
  events: {
    'click .layer-item .indicator': 'toggleVisibility',
    'click .layer-item .content': 'select',
    'click .layer-item .toggle-layer-configuration': 'toggleLayerConfiguration',
    'click .layer-item .btn-delete-layer': 'removeLayer'
  },
  removeLayer: function(e) {
    // The collection belonging to this model, is not the same
    // as the workspace it is in.
    this.model.trigger('removeItem', this.model);
  },
  toggleLayerConfiguration: function() {
    $(this.el).find('.layer-configuration').toggle('fast');
    $(this.el).find('.toggle-layer-configuration i').toggleClass('chevron-closed chevron-open');
  },
  toggleVisibility: function () {
    if(this.model.attributes.visibility) {
      this.model.set({ visibility: false });
    } else {
      this.model.set({ visibility: true });
    }
  },
  select: function(e) {
    if(this.model.get('selected') === false) {
      this.model.collection.each(function(workspaceItem) {
        workspaceItem.set('selected', false);
      });
      this.model.set('selected', true);
      //this.model.trigger('select_layer', this.model);
    }
  }
});

Lizard.Views.ActiveWorkspace = Backbone.Marionette.CollectionView.extend({
  collection: new Lizard.Collections.Layer(), //layerCollection,
  tagName: 'ol',
  className: 'ui-sortable drawer-group wms_sources',
  itemView: Lizard.Views.WorkspaceItem,
  emptyView: Marionette.ItemView.extend({
    template: "#empty-workspace-list-message"
  }),
  events: {
    drop: 'drop'
  },
  initialize: function() {
    this.collection.on('reset', this.render, this);
    this.collection.on('removeItem', this.removeItem, this);
  },
  _initialEvents: function(){
    //this.collection.on("removeItems", this.onItemRemoveds, this);
  },
  drop: function(event, args) {
    debugger;
    this.collection.move(args.item, args.index);
    this.updateOrderFieldOfItems();
    //args.item.set({order: args.index});
    //args.item.attributes.layer.leafletLayer.setZIndex(100 - args.index);
  },
  updateOrderFieldOfItems: function() {
    index=0;
    this.collection.each(function(workspaceItem) {
      workspaceItem.set('order',index);
      index = index + 1;
    });
  },
  setWorkspace: function(workspace) {
    this.model = workspace;
    this.collection.reset(workspace.get('workspaceitems').models);
  },
  removeItem: function(model) {
    this.collection.remove(model);
    this.render();
  },
  onShow: function () {
    var that = this;
    $('.drawer-group').sortable({
      stop: function(event, ui) {
        var item = that.collection.get(ui.item.attr('id'));
        ui.item.trigger('drop', {
          item: item,
          index: ui.item.index()
        });
      }
    });
    $('.drawer-group').disableSelection();
  },
  onClose: function(){
    console.log('closing', this);
  },
  getCollection: function() {
    return this.collection;
  }
});

<|endoftext|>


<commit_before>let escape = require('pg-escape');

let valuePlaceholder = { valuePlaceholder: true };

class SqlA {
    constructor(parts, values) {
        this.parts = parts;
        this.vals = values;
        this.q = null;
    }

    flatten() {
        let parts = [ ];
        let values = [ ];
        this.flattenInto(parts, values);
        let first = 0;
        let flatParts = [ ];
        for (let i = 0; i < parts.length; ++i) {
            if (typeof parts[i] !== 'string') {
                if (first < i)
                    flatParts.push(parts.slice(first, i).join(''));
                flatParts.push(parts[i]);
                first = i + 1;
            }
        }
        if (first < parts.length)
            flatParts.push(parts.slice(first, parts.length).join(''));
        return new SqlA(flatParts, values);
    }

    flattenInto(parts, values) {
        let v = 0;
        for (let part of this.parts) {
            if (part instanceof SqlA) {
                part.flattenInto(parts, values);
            } else if (part === valuePlaceholder) {
                let value = this.vals[v++];
                parts.push(part);
                values.push(value);
            } else {
                parts.push(part);
            }
        }
    }

    computeQuery() {
        if (this.q) return;
        let parts = [ ];
        let values = [ ];
        this.flattenInto(parts, values);
        let paramNumber = 0;
        for (let i = 0; i < parts.length; ++i) {
            if (parts[i] === valuePlaceholder)
                parts[i] = '$' + (++paramNumber);
        }
        this.q = {
            query: parts.join(''),
            values: values,
            anyFunctionValues: values.some(x => x instanceof Function)
        };
    }

    query() {
        this.computeQuery();
        return this.q.query;
    }

    values() {
        this.computeQuery();
        if (this.q.anyFunctionValues) {
            return this.q.values.map(v => {
                if (v instanceof Function)
                    return v.apply(null, arguments);
                return v;
            });
        } else {
            return this.q.values.slice();
        }
    }

    concat(sql) {
        return new SqlA([this, ' ', sql], []);
    }

    parenthesize(sql) {
        return new SqlA(['(', this, ')'], []);
    }

    not() {
        return new SqlA(['NOT ', this], []);
    }
}

function sqlA(parts, ...values) {
    let outParts = new Array(parts.length + values.length);
    let outValues = [ ];

    let p = 0, v = 0;
    for (let i = 0; i < outParts.length; ++i) {
        if (i % 2 == 0) {
            outParts[i] = parts[p++];
        } else {
            let value = values[v++];
            if (value instanceof SqlA) {
                outParts[i] = value;
            } else {
                outParts[i] = valuePlaceholder;
                outValues.push(value);
            }
        }
    }

    return new SqlA(outParts, outValues);
}

sqlA.unsafe = function unsafe(value) {
    return new SqlA([null == value ? '' : String(value)], []);
};

sqlA.ident = function ident(value) {
    return new SqlA([escape.ident(value)], []);
};

sqlA.literal = function literal(value) {
    return new SqlA([escape.literal(value)], []);
};

sqlA.join = function join(values, sep = ' ') {
    let len = values.length;
    if (values.length > 1)
        len += values.length - 1;
    let parts = new Array(len);
    let vals = [];
    for (let i = 0; i < values.length; ++i) {
        if (i > 0)
            parts[i * 2 - 1] = sep;
        if (values[i] instanceof SqlA) {
            parts[i * 2] = values[i];
        } else {
            vals.push(values[i]);
            parts[i * 2] = valuePlaceholder;
        }
    }
    return new SqlA(parts, vals);
};

sqlA.parenthesize = function parenthesize(values) {
    return values.map(x => x.parenthesize());
};

sqlA.and = function and(values) {
    return sqlA.join(values, ' AND ');
};

sqlA.or = function or(values) {
    return sqlA.join(values, ' OR ');
};

sqlA.comma = function or(values) {
    return sqlA.join(values, ', ');
};

sqlA.types = {
    SqlA,
    valuePlaceholder
};

export default sqlA;
<commit_msg>Remove bogus arg to this.parenthesize()<commit_after>let escape = require('pg-escape');

let valuePlaceholder = { valuePlaceholder: true };

class SqlA {
    constructor(parts, values) {
        this.parts = parts;
        this.vals = values;
        this.q = null;
    }

    flatten() {
        let parts = [ ];
        let values = [ ];
        this.flattenInto(parts, values);
        let first = 0;
        let flatParts = [ ];
        for (let i = 0; i < parts.length; ++i) {
            if (typeof parts[i] !== 'string') {
                if (first < i)
                    flatParts.push(parts.slice(first, i).join(''));
                flatParts.push(parts[i]);
                first = i + 1;
            }
        }
        if (first < parts.length)
            flatParts.push(parts.slice(first, parts.length).join(''));
        return new SqlA(flatParts, values);
    }

    flattenInto(parts, values) {
        let v = 0;
        for (let part of this.parts) {
            if (part instanceof SqlA) {
                part.flattenInto(parts, values);
            } else if (part === valuePlaceholder) {
                let value = this.vals[v++];
                parts.push(part);
                values.push(value);
            } else {
                parts.push(part);
            }
        }
    }

    computeQuery() {
        if (this.q) return;
        let parts = [ ];
        let values = [ ];
        this.flattenInto(parts, values);
        let paramNumber = 0;
        for (let i = 0; i < parts.length; ++i) {
            if (parts[i] === valuePlaceholder)
                parts[i] = '$' + (++paramNumber);
        }
        this.q = {
            query: parts.join(''),
            values: values,
            anyFunctionValues: values.some(x => x instanceof Function)
        };
    }

    query() {
        this.computeQuery();
        return this.q.query;
    }

    values() {
        this.computeQuery();
        if (this.q.anyFunctionValues) {
            return this.q.values.map(v => {
                if (v instanceof Function)
                    return v.apply(null, arguments);
                return v;
            });
        } else {
            return this.q.values.slice();
        }
    }

    concat(sql) {
        return new SqlA([this, ' ', sql], []);
    }

    parenthesize() {
        return new SqlA(['(', this, ')'], []);
    }

    not() {
        return new SqlA(['NOT ', this], []);
    }
}

function sqlA(parts, ...values) {
    let outParts = new Array(parts.length + values.length);
    let outValues = [ ];

    let p = 0, v = 0;
    for (let i = 0; i < outParts.length; ++i) {
        if (i % 2 == 0) {
            outParts[i] = parts[p++];
        } else {
            let value = values[v++];
            if (value instanceof SqlA) {
                outParts[i] = value;
            } else {
                outParts[i] = valuePlaceholder;
                outValues.push(value);
            }
        }
    }

    return new SqlA(outParts, outValues);
}

sqlA.unsafe = function unsafe(value) {
    return new SqlA([null == value ? '' : String(value)], []);
};

sqlA.ident = function ident(value) {
    return new SqlA([escape.ident(value)], []);
};

sqlA.literal = function literal(value) {
    return new SqlA([escape.literal(value)], []);
};

sqlA.join = function join(values, sep = ' ') {
    let len = values.length;
    if (values.length > 1)
        len += values.length - 1;
    let parts = new Array(len);
    let vals = [];
    for (let i = 0; i < values.length; ++i) {
        if (i > 0)
            parts[i * 2 - 1] = sep;
        if (values[i] instanceof SqlA) {
            parts[i * 2] = values[i];
        } else {
            vals.push(values[i]);
            parts[i * 2] = valuePlaceholder;
        }
    }
    return new SqlA(parts, vals);
};

sqlA.parenthesize = function parenthesize(values) {
    return values.map(x => x.parenthesize());
};

sqlA.and = function and(values) {
    return sqlA.join(values, ' AND ');
};

sqlA.or = function or(values) {
    return sqlA.join(values, ' OR ');
};

sqlA.comma = function or(values) {
    return sqlA.join(values, ', ');
};

sqlA.types = {
    SqlA,
    valuePlaceholder
};

export default sqlA;
<|endoftext|>


<commit_before>import Firebase from 'firebase';

class ReduxOnFire {
    constructor(config) {
        this.firebaseApp = Firebase.initializeApp(config);
        this.firebaseAuth = Firebase.auth();
        this.firebaseAuthFacebook = new Firebase.auth.FacebookAuthProvider();
        this.firebaseAuthGoogle = new Firebase.auth.GoogleAuthProvider();
        this.firebaseStorage = Firebase.storage();
        this.firebaseDatabase = Firebase.database();
        this.dispatch = null;
        this.getState = null;
    }

    watchAuth() {
        this.firebaseAuth.onAuthStateChanged((result) => {
            if (result) {
                this.dispatch({
                    type: 'USER_LOGGED',
                    result: result
                });
            } else {
                this.dispatch({ type: 'USER_LOGGED_OUT' });
            }
        });
    }

    signup(email, password) {
        this.dispatch({ type: 'SIGNUP_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.createUserWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'SIGNUP_SUCCESS',
                        result: result
                    });

                    resolve(result);

                    let user = this.firebaseAuth.currentUser;
                    if (!user.emailVerified) { user.sendEmailVerification(); }
                })
                .catch(error => {
                    this.dispatch({
                        type: 'SIGNUP_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    login(email, password) {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch(error => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    passwordReset(email) {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.sendPasswordResetEmail(email)
                .then(() => {
                    this.dispatch({ type: 'PASSWORD_RESET_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'PASSWORD_RESET_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    facebook() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthFacebook)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    google() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthGoogle)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    logout() {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signOut()
                .then(() => {
                    this.dispatch({ type: 'LOGOUT_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGOUT_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    watchRecords(recordsName, returnId) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    watchRecordsOrdered(recordsName, returnId, criteria, reverse) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).orderByChild(criteria).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: reverse ? array.reverse() : array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordsFiltered(recordsName, filter) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_FILTERED_REQUEST' });
        this.firebaseDatabase.ref(recordsName).once('value',
            (result) => {
                let array = [];
                result.forEach((child) => {
                    let element = child.val();
                    element.id = child.key;
                    array.push(element);
                });
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_SUCCESS',
                    [recordsName]: filter(array)
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordById(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.dispatch({ type: 'GET_SINGLE_' + actionName + '_REQUEST' });

        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if (record.length == 1) {
            this.dispatch({
                type: 'GET_SINGLE_' + actionName + '_CACHED',
                [recordName]: record[0]
            });
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value',
            (snapshot) => {
                this.dispatch({
                    type: 'GET_SINGLE_' + actionName + '_SUCCESS',
                    [recordName]: snapshot.val()
                });
            },
            (error) => {
                this.dispatch({ type: 'GET_SINGLE_' + actionName + '_FAILED' });
            });
        }
    }

    getRecordByContent(recordName, recordContent) {
        let actionName = recordName.toUpperCase();
        return {
            type: 'GET_' + actionName,
            [recordName]: recordContent
        }
    }

    addRecordKey(recordName) {
        var actionName = recordName.toUpperCase();
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        var initialDB = {
            number: '0/2016'
        }

        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            initialDB,
            (error) => {
                if (error) {
                    console.log(error);
                } else {
                    return dispatch({
                        type: 'ADD_' + actionName,
                        reference: reference
                    });
                }
            }
        );
    }

    addRecordWithContent(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'ADD_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            recordContent,
            (error) => {
                if (error) {
                    return dispatch({type: 'ADD_' + actionName + '_FAILED', notification: notificationFailed});
                } else {
                    return dispatch({type: 'ADD_' + actionName + '_SUCCESS', notification: notificationSuccess});
                };
            }
        );
    }

    updateRecord(recordName, recordId, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'UPDATE_' + actionName + '_REQUEST'});

        if (recordId == null) {
            var reference = this.firebaseDatabase.ref().child(recordName);
        } else {
            var reference = this.firebaseDatabase.ref().child(recordName + '/' + recordId);
        }

        return reference.update(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    setRecord(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'SET_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName);
        return reference.set(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    cloneRecord(recordName, recordId, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'CLONE_' + actionName + '_REQUEST'})
        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if(record.length == 1) {
            var reference = this.firebaseDatabase.ref(recordName).push().key;
            return this.firebaseDatabase.ref(recordName).child(reference).update(
                record[0],
                (error) => {
                    if (error) {
                        return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                    } else {
                        return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                    };
                }
            );
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value').then((snapshot) => {
                var reference = this.firebaseDatabase.ref(recordName).push().key;
                return this.firebaseDatabase.ref(recordName).child(reference).update(
                    snapshot.val(),
                    (error) => {
                        if (error) {
                            return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                        } else {
                            return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                        };
                    }
                );
            });
        }
    }

    deleteRecord(recordName, recordId, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.firebaseDatabase.ref().child(recordName + '/' + recordId).remove();
        return {
            type: 'DELETE_' + actionName,
            id: recordId,
            notification: notificationSuccess
        }
    }

    showNotification(notification) {
        return {
            type: 'SIMPLE_NOTIFICATION',
            notification: notification
        }
    }

}

export default ReduxOnFire;
<commit_msg>UPDATED: notifications API<commit_after>import Firebase from 'firebase';

class ReduxOnFire {
    constructor(config) {
        this.firebaseApp = Firebase.initializeApp(config);
        this.firebaseAuth = Firebase.auth();
        this.firebaseAuthFacebook = new Firebase.auth.FacebookAuthProvider();
        this.firebaseAuthGoogle = new Firebase.auth.GoogleAuthProvider();
        this.firebaseStorage = Firebase.storage();
        this.firebaseDatabase = Firebase.database();
        this.dispatch = null;
        this.getState = null;
    }

    watchAuth() {
        this.firebaseAuth.onAuthStateChanged((result) => {
            if (result) {
                this.dispatch({
                    type: 'USER_LOGGED',
                    result: result
                });
            } else {
                this.dispatch({ type: 'USER_LOGGED_OUT' });
            }
        });
    }

    signup(email, password) {
        this.dispatch({ type: 'SIGNUP_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.createUserWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'SIGNUP_SUCCESS',
                        result: result
                    });

                    resolve(result);

                    let user = this.firebaseAuth.currentUser;
                    if (!user.emailVerified) { user.sendEmailVerification(); }
                })
                .catch(error => {
                    this.dispatch({
                        type: 'SIGNUP_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    login(email, password) {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch(error => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    passwordReset(email) {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.sendPasswordResetEmail(email)
                .then(() => {
                    this.dispatch({ type: 'PASSWORD_RESET_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'PASSWORD_RESET_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    facebook() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthFacebook)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    google() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthGoogle)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    logout() {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signOut()
                .then(() => {
                    this.dispatch({ type: 'LOGOUT_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGOUT_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    watchRecords(recordsName, returnId) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    watchRecordsOrdered(recordsName, returnId, criteria, reverse) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).orderByChild(criteria).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: reverse ? array.reverse() : array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordsFiltered(recordsName, filter) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_FILTERED_REQUEST' });
        this.firebaseDatabase.ref(recordsName).once('value',
            (result) => {
                let array = [];
                result.forEach((child) => {
                    let element = child.val();
                    element.id = child.key;
                    array.push(element);
                });
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_SUCCESS',
                    [recordsName]: filter(array)
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordById(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.dispatch({ type: 'GET_SINGLE_' + actionName + '_REQUEST' });

        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if (record.length == 1) {
            this.dispatch({
                type: 'GET_SINGLE_' + actionName + '_CACHED',
                [recordName]: record[0]
            });
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value',
            (snapshot) => {
                this.dispatch({
                    type: 'GET_SINGLE_' + actionName + '_SUCCESS',
                    [recordName]: snapshot.val()
                });
            },
            (error) => {
                this.dispatch({ type: 'GET_SINGLE_' + actionName + '_FAILED' });
            });
        }
    }

    getRecordByContent(recordName, recordContent) {
        let actionName = recordName.toUpperCase();
        return {
            type: 'GET_' + actionName,
            [recordName]: recordContent
        }
    }

    addRecordKey(recordName) {
        var actionName = recordName.toUpperCase();
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        var initialDB = {
            number: '0/2016'
        }

        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            initialDB,
            (error) => {
                if (error) {
                    console.log(error);
                } else {
                    return dispatch({
                        type: 'ADD_' + actionName,
                        reference: reference
                    });
                }
            }
        );
    }

    addRecordWithContent(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'ADD_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            recordContent,
            (error) => {
                if (error) {
                    return dispatch({type: 'ADD_' + actionName + '_FAILED', notification: notificationFailed});
                } else {
                    return dispatch({type: 'ADD_' + actionName + '_SUCCESS', notification: notificationSuccess});
                };
            }
        );
    }

    updateRecord(recordName, recordId, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'UPDATE_' + actionName + '_REQUEST'});

        if (recordId == null) {
            var reference = this.firebaseDatabase.ref().child(recordName);
        } else {
            var reference = this.firebaseDatabase.ref().child(recordName + '/' + recordId);
        }

        return reference.update(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    setRecord(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'SET_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName);
        return reference.set(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    cloneRecord(recordName, recordId, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'CLONE_' + actionName + '_REQUEST'})
        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if(record.length == 1) {
            var reference = this.firebaseDatabase.ref(recordName).push().key;
            return this.firebaseDatabase.ref(recordName).child(reference).update(
                record[0],
                (error) => {
                    if (error) {
                        return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                    } else {
                        return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                    };
                }
            );
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value').then((snapshot) => {
                var reference = this.firebaseDatabase.ref(recordName).push().key;
                return this.firebaseDatabase.ref(recordName).child(reference).update(
                    snapshot.val(),
                    (error) => {
                        if (error) {
                            return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                        } else {
                            return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                        };
                    }
                );
            });
        }
    }

    deleteRecord(recordName, recordId, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.firebaseDatabase.ref().child(recordName + '/' + recordId).remove();
        return {
            type: 'DELETE_' + actionName,
            id: recordId,
            notification: notificationSuccess
        }
    }

    addNotification(notification) {
        const newNotification = Object.assign({}, notification);
        newNotification.id = new Date().getTime();
        this.dispatch({
            type: 'ADD_NOTIFICATION',
            newNotification
        });

        if (newNotification.removeAfter) {
            setTimeout(() => {
                this.dispatch({
                    type: 'REMOVE_NOTIFICATION',
                    id: newNotification.id,
                });
            }, newNotification.removeAfter);
        }
    }

    removeNotification(id) {
        this.dispatch({
            type: 'REMOVE_NOTIFICATION',
            id: id
        });
    }

    clearNotifications() {
        this.dispatch({
            type: 'CLEAR_NOTIFICATIONS'
        });
    }

}

export default ReduxOnFire;
<|endoftext|>