<commit_before>/*
 * Copyright (C) 2012-2013 Vanderbilt University, All rights reserved.
 *
 * Author: Tamas Kecskes
 */
var COREVERSION = "3";
define(['commonUtil','core/core'+COREVERSION,'core/assert','logManager'], function (CU,CORE,ASSERT,logManager) {
    'use strict';
    var GUID = CU.guid;
    var TSSTRING = function(){
        return "["+CU.timestamp()+"]";
    };
    var TIMESTAMP = CU.timestamp;
    var ETIMESTRING = function(start){
        return "{"+ (TIMESTAMP()-start) + "ms}";
    };

    // ----------------- Core -----------------

    var ClientLogCore = function (options) {
        ASSERT(options && options.storage);
        var log = null,
            logger = logManager.create("CORE"),
            core = new CORE(options.storage);
        log = function(msg){
            logger.debug(msg);
        };

        //check
        var isValidRelid = function (relid) {
            log("isValidRelid("+relid+")");
            return core.isValidRelid(relid);
        };
        var isValidPath = function (path) {
            log("isValidPath("+path+")");
            return core.isValidPath(path);
        };
        var isValidNode = function (node) {
            log("isValidNode("+node["data"]["_id"]+")");
            return core.isValidNode(node);
        };

        //root
        var getKey = function (node) {
            log("getKey("+node["data"]["_id"]+"))");
            return core.getKey(node);
        };
        var loadRoot = function (key, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadRoot("+key+")";
            log(text);
            core.loadRoot(key,function(err,node){
                log(text+ETIMESTRING(start));
                callback(err,node);
            });
        };
        var persist = function (root, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"persist("+root["_id"]+")";
            log(text);
            return core.persist(root,function(err){
                log(text+ETIMESTRING(start));
                callback(err);
            });
        };
        var getRoot = function (node) {
            log("getRoot("+node["data"]["_id"]+")");
            return core.getRoot(node);
        };

        // containment
        var getLevel = function (node, base) {
            log("getLevel("+node["data"]["_id"]+","+base["_id"]+")");
            return core.getLevel(node,base);
        };
        var getRelid = function (node) {
            log("getRelid("+node["data"]["_id"]+")");
            return core.getRelid(node);
        };
        var getStringPath = function (node, base) {
            log("getStringPath("+node["data"]["_id"]+","+ ( base === undefined ? base : base["_id"] ) +")");
            return core.getStringPath(node,base);
        };
        var parseStringPath = function (path) {
            log("parseStringPath("+path+")");
            return core.parseStringPath(path);
        };
        var getParent = function (node) {
            log("getParent("+node["data"]["_id"]+")");
            return core.getParent(node);
        };
        var getChildrenRelids = function (node) {
            log("getChildrenRelids("+node["data"]["_id"]+")");
            return core.getChildrenRelids(node);
        };
        var getChildrenPaths = function (node) {
            log("getChildrenPaths("+node["data"]["_id"]+")");
            return core.getChildrenPaths(node);
        };
        var loadChild = function (node, relid, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadChild("+node["data"]["_id"]+","+relid+")";
            log(text);
            core.loadChild(node,relid,function(err,child){
                log(text+ETIMESTRING(start));
                callback(err,child);
            });
        };
        var loadByPath = function (node, path, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadByPath("+node["data"]["_id"]+","+path+")";
            log(text);
            core.loadByPath(node,path,function(err,node){
                log(text+ETIMESTRING(start));
                callback(err,node);
            });
        };
        var loadChildren = function (node, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadChildren("+node["data"]["_id"]+")";
            log(text);
            core.loadChildren(node,function(err,children){
                log(text+ETIMESTRING(start));
                callback(err,children);
            });
        };

        // modify
        var createNode = function (parent, relid) {
            if(parent){
                log("createNode("+parent["_id"]+","+relid+")");
            } else {
                log("createNode(null,"+relid+")");
            }
            return core.createNode(parent,relid);
        };
        var deleteNode = function (node) {
            log("deleteNode("+node["data"]["_id"]+")");
            return core.deleteNode(node);
        };
        var copyNode = function (node, parent) {
            log("copyNode("+node["data"]["_id"]+","+parent["_id"]+")");
            return core.copyNode(node,parent);
        };
        var moveNode = function (node, parent) {
            log("moveNode("+node["data"]["_id"]+","+parent["_id"]+")");
            return core.moveNode(node,parent);
        };

        // attributes
        var getAttributeNames = function (node) {
            log("getAttributeNames("+node["data"]["_id"]+")");
            return core.getAttributeNames(node);
        };

        var getAttribute = function (node, name) {
            log("getAttribute("+node["data"]["_id"]+","+name+")");
            return core.getAttribute(node,name);
        };

        var delAttribute = function (node, name) {
            log("delAttribute("+node["data"]["_id"]+","+name+")");
            return core.delAttribute(node,name);

        };

        var setAttribute = function (node, name, value) {
            log("setAttribute("+node["data"]["_id"]+","+name+","+value+")");
            return core.setAttribute(node,name,value);
        };

        var getRegistryNames = function (node) {
            log("getRegistryNames("+node["data"]["_id"]+")");
            return core.getRegistryNames(node);
        };

        var getRegistry = function (node, name) {
            log("getRegistry("+node["data"]["_id"]+","+name+")");
            return core.getRegistry(node,name);
        };

        var delRegistry = function (node, name) {
            log("delRegistry("+node["data"]["_id"]+","+name+")");
            return core.delRegistry(node,name);
        };

        var setRegistry = function (node, name, value) {
            log("setRegistry("+node["data"]["_id"]+","+name+","+value+")");
            return core.setRegistry(node,name,value);
        };

        // relations
        var getPointerNames = function (node) {
            log("getPointerNames("+node["data"]["_id"]+")");
            return core.getPointerNames(node);
        };
        var getPointerPath = function (node, name) {
            log("getPointerPath("+node["data"]["_id"]+","+name+")");
            return core.getPointerPath(node,name);
        };
        var getOutsidePointerPath = function (node, name, source) {
            log("getOutsidePointerPath("+node["data"]["_id"]+","+name+","+source["_id"]+")");
            return core.getOutsidePointerPath(node,name,source);
        };
        var loadPointer = function (node, name, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadPointer("+node["data"]["_id"]+","+name+")";
            log(text);
            core.loadPointer(node,name,function(err,target){
                log(text+ETIMESTRING(start));
                callback(err,target);
            });
        };
        var deletePointer = function (node, name) {
            log("deletePointer("+node["data"]["_id"]+","+name+")");
            return core.deletePointer(node,name);
        };
        var setPointer = function (node, name, target) {
            log("setPointer("+node["data"]["_id"]+","+name+","+target["_id"]+")");
            return core.setPointer(node,name,target);
        };
        var getCollectionNames = function (node) {
            log("getCollectionNames("+node["data"]["_id"]+")");
            return core.getCollectionNames(node);
        };
        var getCollectionPaths = function (node, name) {
            log("getCollectionPaths("+node["data"]["_id"]+","+name+")");
            return core.getCollectionPaths(node,name);
        };
        var loadCollection = function (node, name, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadCollection("+node["data"]["_id"]+","+name+")";
            log(text);
            core.loadCollection(node,name,function(err,collection){
                log(text+ETIMESTRING(start));
                callback(err,collection);
            });
        };

        var getSingleNodeHash = function (node) {
            log("getSingleNodeHash("+node["data"]["_id"]+")");
            return core.getSingleNodeHash(node);
        };

        return {
            // check
            isValidNode: isValidNode,
            isValidRelid: isValidRelid,
            isValidPath: isValidPath,

            // root
            getKey: getKey,
            loadRoot: loadRoot,
            persist: persist,
            getRoot: getRoot,

            // containment
            getLevel: getLevel,
            getRelid: getRelid,
            getStringPath: getStringPath,
            parseStringPath: parseStringPath,
            getParent: getParent,
            getChildrenRelids: getChildrenRelids,
            getChildrenPaths: getChildrenPaths,
            loadChild: loadChild,
            loadByPath: loadByPath,
            loadChildren: loadChildren,

            // modify
            createNode: createNode,
            deleteNode: deleteNode,
            copyNode: copyNode,
            moveNode: moveNode,

            // attributes
            getAttributeNames: getAttributeNames,
            getAttribute: getAttribute,
            setAttribute: setAttribute,
            delAttribute: delAttribute,
            getRegistry: getRegistry,
            setRegistry: setRegistry,
            delRegistry: delRegistry,
            getRegistryNames: getRegistryNames,

            // relations
            getPointerNames: getPointerNames,
            getPointerPath: getPointerPath,
            getOutsidePointerPath: getOutsidePointerPath,
            loadPointer: loadPointer,
            deletePointer: deletePointer,
            setPointer: setPointer,
            getCollectionNames: getCollectionNames,
            getCollectionPaths: getCollectionPaths,
            loadCollection: loadCollection,

            getSingleNodeHash: getSingleNodeHash,

            getVersion: function(){return COREVERSION;}
        };
    };

    return ClientLogCore;
});

<commit_msg>do not mess with the internals of nodes<commit_after>/*
 * Copyright (C) 2012-2013 Vanderbilt University, All rights reserved.
 *
 * Author: Tamas Kecskes
 */
var COREVERSION = "3";
define(['commonUtil','core/core'+COREVERSION,'core/assert','logManager'], function (CU,CORE,ASSERT,logManager) {
    'use strict';
    var GUID = CU.guid;
    var TSSTRING = function(){
        return "["+CU.timestamp()+"]";
    };
    var TIMESTAMP = CU.timestamp;
    var ETIMESTRING = function(start){
        return "{"+ (TIMESTAMP()-start) + "ms}";
    };

    // ----------------- Core -----------------

    var ClientLogCore = function (options) {
        ASSERT(options && options.storage);
        var log = null,
            logger = logManager.create("CORE"),
            core = new CORE(options.storage);
        log = function(msg){
            logger.debug(msg);
        };

        //check
        var isValidRelid = function (relid) {
            log("isValidRelid("+relid+")");
            return core.isValidRelid(relid);
        };
        var isValidPath = function (path) {
            log("isValidPath("+path+")");
            return core.isValidPath(path);
        };
        var isValidNode = function (node) {
            log("isValidNode("+core.getKey(node)+")");
            return core.isValidNode(node);
        };

        //root
        var getKey = function (node) {
            log("getKey("+core.getKey(node)+"))");
            return core.getKey(node);
        };
        var loadRoot = function (key, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadRoot("+key+")";
            log(text);
            core.loadRoot(key,function(err,node){
                log(text+ETIMESTRING(start));
                callback(err,node);
            });
        };
        var persist = function (root, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"persist("+core.getKey(root)+")";
            log(text);
            return core.persist(root,function(err){
                log(text+ETIMESTRING(start));
                callback(err);
            });
        };
        var getRoot = function (node) {
            log("getRoot("+core.getKey(node)+")");
            return core.getRoot(node);
        };

        // containment
        var getLevel = function (node, base) {
            log("getLevel("+core.getKey(node)+","+core.getKey(base)+")");
            return core.getLevel(node,base);
        };
        var getRelid = function (node) {
            log("getRelid("+core.getKey(node)+")");
            return core.getRelid(node);
        };
        var getStringPath = function (node, base) {
            log("getStringPath("+core.getKey(node)+","+ ( base === undefined ? base : core.getKey(base)) +")");
            return core.getStringPath(node,base);
        };
        var parseStringPath = function (path) {
            log("parseStringPath("+path+")");
            return core.parseStringPath(path);
        };
        var getParent = function (node) {
            log("getParent("+core.getKey(node)+")");
            return core.getParent(node);
        };
        var getChildrenRelids = function (node) {
            log("getChildrenRelids("+core.getKey(node)+")");
            return core.getChildrenRelids(node);
        };
        var getChildrenPaths = function (node) {
            log("getChildrenPaths("+core.getKey(node)+")");
            return core.getChildrenPaths(node);
        };
        var loadChild = function (node, relid, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadChild("+core.getKey(node)+","+relid+")";
            log(text);
            core.loadChild(node,relid,function(err,child){
                log(text+ETIMESTRING(start));
                callback(err,child);
            });
        };
        var loadByPath = function (node, path, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadByPath("+core.getKey(node)+","+path+")";
            log(text);
            core.loadByPath(node,path,function(err,node){
                log(text+ETIMESTRING(start));
                callback(err,node);
            });
        };
        var loadChildren = function (node, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadChildren("+core.getKey(node)+")";
            log(text);
            core.loadChildren(node,function(err,children){
                log(text+ETIMESTRING(start));
                callback(err,children);
            });
        };

        // modify
        var createNode = function (parent, relid) {
            if(parent){
                log("createNode("+core.getKey(parent)+","+relid+")");
            } else {
                log("createNode(null,"+relid+")");
            }
            return core.createNode(parent,relid);
        };
        var deleteNode = function (node) {
            log("deleteNode("+core.getKey(node)+")");
            return core.deleteNode(node);
        };
        var copyNode = function (node, parent) {
            log("copyNode("+core.getKey(node)+","+core.getKey(parent)+")");
            return core.copyNode(node,parent);
        };
        var moveNode = function (node, parent) {
            log("moveNode("+core.getKey(node)+","+core.getKey(parent)+")");
            return core.moveNode(node,parent);
        };

        // attributes
        var getAttributeNames = function (node) {
            log("getAttributeNames("+core.getKey(node)+")");
            return core.getAttributeNames(node);
        };

        var getAttribute = function (node, name) {
            log("getAttribute("+core.getKey(node)+","+name+")");
            return core.getAttribute(node,name);
        };

        var delAttribute = function (node, name) {
            log("delAttribute("+core.getKey(node)+","+name+")");
            return core.delAttribute(node,name);

        };

        var setAttribute = function (node, name, value) {
            log("setAttribute("+core.getKey(node)+","+name+","+value+")");
            return core.setAttribute(node,name,value);
        };

        var getRegistryNames = function (node) {
            log("getRegistryNames("+core.getKey(node)+")");
            return core.getRegistryNames(node);
        };

        var getRegistry = function (node, name) {
            log("getRegistry("+core.getKey(node)+","+name+")");
            return core.getRegistry(node,name);
        };

        var delRegistry = function (node, name) {
            log("delRegistry("+core.getKey(node)+","+name+")");
            return core.delRegistry(node,name);
        };

        var setRegistry = function (node, name, value) {
            log("setRegistry("+core.getKey(node)+","+name+","+value+")");
            return core.setRegistry(node,name,value);
        };

        // relations
        var getPointerNames = function (node) {
            log("getPointerNames("+core.getKey(node)+")");
            return core.getPointerNames(node);
        };
        var getPointerPath = function (node, name) {
            log("getPointerPath("+core.getKey(node)+","+name+")");
            return core.getPointerPath(node,name);
        };
        var getOutsidePointerPath = function (node, name, source) {
            log("getOutsidePointerPath("+core.getKey(node)+","+name+","+core.getKey(source)+")");
            return core.getOutsidePointerPath(node,name,source);
        };
        var loadPointer = function (node, name, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadPointer("+core.getKey(node)+","+name+")";
            log(text);
            core.loadPointer(node,name,function(err,target){
                log(text+ETIMESTRING(start));
                callback(err,target);
            });
        };
        var deletePointer = function (node, name) {
            log("deletePointer("+core.getKey(node)+","+name+")");
            return core.deletePointer(node,name);
        };
        var setPointer = function (node, name, target) {
            log("setPointer("+core.getKey(node)+","+name+","+core.getKey(target)+")");
            return core.setPointer(node,name,target);
        };
        var getCollectionNames = function (node) {
            log("getCollectionNames("+core.getKey(node)+")");
            return core.getCollectionNames(node);
        };
        var getCollectionPaths = function (node, name) {
            log("getCollectionPaths("+core.getKey(node)+","+name+")");
            return core.getCollectionPaths(node,name);
        };
        var loadCollection = function (node, name, callback) {
            var start = TIMESTAMP();
            var guid = "["+GUID()+"]";
            var text = guid+"loadCollection("+core.getKey(node)+","+name+")";
            log(text);
            core.loadCollection(node,name,function(err,collection){
                log(text+ETIMESTRING(start));
                callback(err,collection);
            });
        };

        var getSingleNodeHash = function (node) {
            log("getSingleNodeHash("+core.getKey(node)+")");
            return core.getSingleNodeHash(node);
        };

        return {
            // check
            isValidNode: isValidNode,
            isValidRelid: isValidRelid,
            isValidPath: isValidPath,

            // root
            getKey: getKey,
            loadRoot: loadRoot,
            persist: persist,
            getRoot: getRoot,

            // containment
            getLevel: getLevel,
            getRelid: getRelid,
            getStringPath: getStringPath,
            parseStringPath: parseStringPath,
            getParent: getParent,
            getChildrenRelids: getChildrenRelids,
            getChildrenPaths: getChildrenPaths,
            loadChild: loadChild,
            loadByPath: loadByPath,
            loadChildren: loadChildren,

            // modify
            createNode: createNode,
            deleteNode: deleteNode,
            copyNode: copyNode,
            moveNode: moveNode,

            // attributes
            getAttributeNames: getAttributeNames,
            getAttribute: getAttribute,
            setAttribute: setAttribute,
            delAttribute: delAttribute,
            getRegistry: getRegistry,
            setRegistry: setRegistry,
            delRegistry: delRegistry,
            getRegistryNames: getRegistryNames,

            // relations
            getPointerNames: getPointerNames,
            getPointerPath: getPointerPath,
            getOutsidePointerPath: getOutsidePointerPath,
            loadPointer: loadPointer,
            deletePointer: deletePointer,
            setPointer: setPointer,
            getCollectionNames: getCollectionNames,
            getCollectionPaths: getCollectionPaths,
            loadCollection: loadCollection,

            getSingleNodeHash: getSingleNodeHash,

            getVersion: function(){return COREVERSION;}
        };
    };

    return ClientLogCore;
});

<|endoftext|>


<commit_before>/* @flow */
import { replaceFilters } from '@ncigdc/utils/filters';
import memoize from 'memoizee';
import { fetchApi } from '@ncigdc/utils/ajax';
import Queue from 'queue';
import md5 from 'blueimp-md5';

async function getGenes({
  currentFilters,
  size = 50,
}: {
  currentFilters: Object,
  size: number,
}): Promise<Object> {
  const fields = ['gene_id', 'symbol', 'is_cancer_gene_census'];

  return fetchApi(
    `analysis/top_mutated_genes_by_project?size=${size}&fields=${fields.join()}${currentFilters
      .content.length
      ? `&filters=${JSON.stringify(currentFilters)}`
      : ''}`,
  );
}

const OCCURRENCE_CHUNK = 10000;
async function getOccurrences(args: {
  geneIds: Array<string>,
  caseIds: Array<string>,
  currentFilters: Object,
}): Promise<Object> {
  const queue = Queue({ concurrency: 6 });
  const { geneIds, caseIds, currentFilters } = args;

  if (!geneIds.length || !caseIds.length) return { data: { hits: [] } };

  const filters = replaceFilters(
    {
      op: 'and',
      content: [
        { op: 'in', content: { field: 'genes.gene_id', value: geneIds } },
        { op: 'in', content: { field: 'cases.case_id', value: caseIds } },
      ],
    },
    currentFilters,
  );

  const fields = [
    'ssm.consequence.transcript.consequence_type',
    'ssm.consequence.transcript.annotation.impact',
    'ssm.consequence.transcript.gene.gene_id',
    'ssm.ssm_id',
    'case.case_id',
  ];

  const firstSize = 0;
  const defaultOptions = {
    headers: { 'Content-Type': 'application/json' },
    body: {
      filters,
      size: firstSize,
      from: 0,
      fields: fields.join(),
      sort: '_uid', // force consistent order
    },
  };
  const hash = md5(JSON.stringify(defaultOptions));
  const { data } = await fetchApi(`ssm_occurrences?hash=${hash}`, {
    ...defaultOptions,
  });
  let hits = data.hits;

  for (
    let count = firstSize;
    count < data.pagination.total;
    count += OCCURRENCE_CHUNK
  ) {
    // eslint-disable-next-line no-loop-func
    queue.push(callback => {
      const options = {
        ...defaultOptions,
        body: {
          ...defaultOptions.body,
          from: count,
          size: OCCURRENCE_CHUNK,
        },
      };
      const hash = md5(JSON.stringify(options));
      fetchApi(`ssm_occurrences?hash=${hash}`, options).then(response => {
        hits = [...hits, ...response.data.hits];
        callback();
      });
    });
  }

  return new Promise((resolve, reject) => {
    queue.start(err => {
      if (err) {
        reject(err);
      } else {
        resolve({ data: { hits } });
      }
    });
  });
}

async function getCases({
  geneIds,
  currentFilters,
  size = 50,
}: {
  geneIds: Array<string>,
  currentFilters: Object,
  size: number,
}): Promise<Object> {
  if (!geneIds.length) return { data: { hits: [] } };

  const filters = replaceFilters(
    {
      op: 'and',
      content: [
        { op: 'in', content: { field: 'genes.gene_id', value: geneIds } },
      ],
    },
    currentFilters,
  );

  return fetchApi('analysis/top_mutated_cases_by_gene', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: {
      filters,
      size,
      fields: [
        'diagnoses.days_to_death',
        'diagnoses.age_at_diagnosis',
        'diagnoses.vital_status',
        'demographic.gender',
        'demographic.race',
        'demographic.ethnicity',
        'case_id',
        'summary.data_categories.file_count',
        'summary.data_categories.data_category',
      ].join(),
    },
  });
}

async function getQueries({
  currentFilters,
  maxGenes,
  maxCases,
}: {
  currentFilters: Object,
  maxGenes: number,
  maxCases: number,
}): Promise<Object> {
  const { data } = await getGenes({ currentFilters, size: maxGenes });
  const genes = data.hits;
  const geneIds = genes.map(gene => gene.gene_id);
  const cases = await getCases({ geneIds, currentFilters, size: maxCases });
  const caseIds = cases.data.hits.map(c => c.case_id);
  const occurrences = await getOccurrences({
    geneIds,
    currentFilters,
    caseIds,
  });

  return {
    genes,
    occurences: occurrences.data.hits,
    cases: cases.data.hits,
    totalCases: cases.data.pagination.total,
  };
}

export default memoize(getQueries, {
  promise: true,
  normalizer: args => JSON.stringify(args[0]),
  max: 10,
});
<commit_msg>🐛 [PRTL-1340] fix grid infinit loading with no data<commit_after>/* @flow */
import { replaceFilters } from '@ncigdc/utils/filters';
import memoize from 'memoizee';
import { fetchApi } from '@ncigdc/utils/ajax';
import Queue from 'queue';
import md5 from 'blueimp-md5';

async function getGenes({
  currentFilters,
  size = 50,
}: {
  currentFilters: Object,
  size: number,
}): Promise<Object> {
  const fields = ['gene_id', 'symbol', 'is_cancer_gene_census'];

  return fetchApi(
    `analysis/top_mutated_genes_by_project?size=${size}&fields=${fields.join()}${currentFilters
      .content.length
      ? `&filters=${JSON.stringify(currentFilters)}`
      : ''}`,
  );
}

const OCCURRENCE_CHUNK = 10000;
async function getOccurrences(args: {
  geneIds: Array<string>,
  caseIds: Array<string>,
  currentFilters: Object,
}): Promise<Object> {
  const queue = Queue({ concurrency: 6 });
  const { geneIds, caseIds, currentFilters } = args;

  if (!geneIds.length || !caseIds.length) return { data: { hits: [] } };

  const filters = replaceFilters(
    {
      op: 'and',
      content: [
        { op: 'in', content: { field: 'genes.gene_id', value: geneIds } },
        { op: 'in', content: { field: 'cases.case_id', value: caseIds } },
      ],
    },
    currentFilters,
  );

  const fields = [
    'ssm.consequence.transcript.consequence_type',
    'ssm.consequence.transcript.annotation.impact',
    'ssm.consequence.transcript.gene.gene_id',
    'ssm.ssm_id',
    'case.case_id',
  ];

  const firstSize = 0;
  const defaultOptions = {
    headers: { 'Content-Type': 'application/json' },
    body: {
      filters,
      size: firstSize,
      from: 0,
      fields: fields.join(),
      sort: '_uid', // force consistent order
    },
  };
  const hash = md5(JSON.stringify(defaultOptions));
  const { data } = await fetchApi(`ssm_occurrences?hash=${hash}`, {
    ...defaultOptions,
  });
  let hits = data.hits;

  for (
    let count = firstSize;
    count < data.pagination.total;
    count += OCCURRENCE_CHUNK
  ) {
    // eslint-disable-next-line no-loop-func
    queue.push(callback => {
      const options = {
        ...defaultOptions,
        body: {
          ...defaultOptions.body,
          from: count,
          size: OCCURRENCE_CHUNK,
        },
      };
      const hash = md5(JSON.stringify(options));
      fetchApi(`ssm_occurrences?hash=${hash}`, options).then(response => {
        hits = [...hits, ...response.data.hits];
        callback();
      });
    });
  }

  return new Promise((resolve, reject) => {
    queue.start(err => {
      if (err) {
        reject(err);
      } else {
        resolve({ data: { hits } });
      }
    });
  });
}

async function getCases({
  geneIds,
  currentFilters,
  size = 50,
}: {
  geneIds: Array<string>,
  currentFilters: Object,
  size: number,
}): Promise<Object> {
  if (!geneIds.length) return { data: { hits: [], pagination: { total: 0 } } };

  const filters = replaceFilters(
    {
      op: 'and',
      content: [
        { op: 'in', content: { field: 'genes.gene_id', value: geneIds } },
      ],
    },
    currentFilters,
  );

  return fetchApi('analysis/top_mutated_cases_by_gene', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: {
      filters,
      size,
      fields: [
        'diagnoses.days_to_death',
        'diagnoses.age_at_diagnosis',
        'diagnoses.vital_status',
        'demographic.gender',
        'demographic.race',
        'demographic.ethnicity',
        'case_id',
        'summary.data_categories.file_count',
        'summary.data_categories.data_category',
      ].join(),
    },
  });
}

async function getQueries({
  currentFilters,
  maxGenes,
  maxCases,
}: {
  currentFilters: Object,
  maxGenes: number,
  maxCases: number,
}): Promise<Object> {
  const { data } = await getGenes({ currentFilters, size: maxGenes });
  const genes = data.hits;
  const geneIds = genes.map(gene => gene.gene_id);
  const cases = await getCases({ geneIds, currentFilters, size: maxCases });
  const caseIds = cases.data.hits.map(c => c.case_id);
  const occurrences = await getOccurrences({
    geneIds,
    currentFilters,
    caseIds,
  });

  return {
    genes,
    occurences: occurrences.data.hits,
    cases: cases.data.hits,
    totalCases: cases.data.pagination.total,
  };
}

export default memoize(getQueries, {
  promise: true,
  normalizer: args => JSON.stringify(args[0]),
  max: 10,
});
<|endoftext|>


<commit_before>angular.module('ot.view.validationStamp', [
    'ui.router',
    'ot.service.core',
    'ot.service.structure'
])
    .config(function ($stateProvider) {
        $stateProvider.state('validationStamp', {
            url: '/validationStamp/{validationStampId}',
            templateUrl: 'app/view/view.validationStamp.tpl.html',
            controller: 'ValidationStampCtrl'
        });
    })
    .controller('ValidationStampCtrl', function ($state, $scope, $stateParams, $http, ot, otStructureService, otAlertService, otGraphqlService) {
        const view = ot.view();
        let viewInitialised = false;
        // ValidationStamp's id
        const validationStampId = $stateParams.validationStampId;

        // Initial query parameters
        const queryVariables = {
            validationStampId: validationStampId,
            offset: 0,
            size: 20
        };

        // Query for the validation stamp
        const query = `
            query PaginatedValidationRuns($validationStampId: Int!, $offset: Int = 0, $size: Int = 20) {
                validationStamp(id: $validationStampId) {
                    id
                    name
                    description
                    image
                    _image
                    decorations {
                      decorationType
                      data
                      error
                      feature {
                        id
                      }
                    }
                    branch {
                      id
                      name
                      project {
                        id
                        name
                      }
                    }
                    links {
                      _self
                      _bulkUpdate
                      _update
                      _delete
                      _properties
                      _events
                    }
                    validationRunsPaginated(offset: $offset, size: $size) {
                      pageInfo {
                        totalSize
                        currentOffset
                        currentSize
                        previousPage {
                          offset
                          size
                        }
                        nextPage {
                          offset
                          size
                        }
                        pageIndex
                        pageTotal
                      }
                      pageItems {
                        id
                        runOrder
                        build {
                          name
                        }
                        validationRunStatuses {
                          statusID {
                            id
                            name
                          }
                          description
                          creation {
                            user
                            time
                          }
                        }
                      }
                    }
                }
            }`;

        // Loading the validation stamp
        function loadValidationStamp() {
            otGraphqlService.pageGraphQLCall(query, queryVariables).then(function (data) {
                const validationStamp = data.validationStamp;
                $scope.validationStamp = validationStamp;
                // View setup
                if (!viewInitialised) {
                    // View title
                    view.breadcrumbs = ot.branchBreadcrumbs(validationStamp.branch);
                    // Commands
                    view.commands = [
                        {
                            condition: function () {
                                return validationStamp.links._update;
                            },
                            id: 'updateValidationStampImage',
                            name: "Change image",
                            cls: 'ot-command-validation-stamp-image',
                            action: changeImage
                        },
                        {
                            condition: function () {
                                return validationStamp.links._update;
                            },
                            id: 'updateValidationStamp',
                            name: "Update validation stamp",
                            cls: 'ot-command-validation-stamp-update',
                            action: function () {
                                otStructureService.update(
                                    validationStamp.links._update,
                                    "Update validation stamp"
                                ).then(loadValidationStamp);
                            }
                        },
                        {
                            condition: function () {
                                return validationStamp.links._delete;
                            },
                            id: 'deleteValidationStamp',
                            name: "Delete validation stamp",
                            cls: 'ot-command-validation-stamp-delete',
                            action: function () {
                                otAlertService.confirm({
                                    title: "Deleting a validation stamp",
                                    message: "Do you really want to delete the validation stamp " + validationStamp.name +
                                    " and all its associated data?"
                                }).then(function () {
                                    return ot.call($http.delete(validationStamp.links._delete));
                                }).then(function () {
                                    $state.go('branch', {branchId: validationStamp.branch.id});
                                });
                            }
                        },
                        {
                            condition: function () {
                                return validationStamp.links._bulkUpdate;
                            },
                            id: 'bulkUpdateValidationStamp',
                            name: "Bulk update",
                            cls: 'ot-command-update',
                            action: function () {
                                otAlertService.confirm({
                                    title: "Validation stamps bulk update",
                                    message: "Updates all other validation stamps with the same name?"
                                }).then(function () {
                                    return ot.call($http.put(validationStamp.links._bulkUpdate, {}));
                                }).then(loadValidationStamp);
                            }
                        },
                        ot.viewApiCommand($scope.validationStamp.links._self),
                        ot.viewCloseCommand('/branch/' + $scope.validationStamp.branch.id)
                    ];
                    // View OK now
                    viewInitialised = true;
                }
            });
        }

        // Initialisation
        loadValidationStamp();

        // Changing the image
        function changeImage() {
            otStructureService.changeValidationStampImage($scope.validationStamp).then(loadValidationStamp);
        }

        // Switching the page
        $scope.switchPage = function (pageLink) {
            ot.pageCall($http.get(pageLink)).then(function (validationRunResources) {
                $scope.validationRunResources = validationRunResources;
            });
        };

    })
;<commit_msg>#600 VS page - decorations<commit_after>angular.module('ot.view.validationStamp', [
    'ui.router',
    'ot.service.core',
    'ot.service.structure',
    'ot.service.graphql'
])
    .config(function ($stateProvider) {
        $stateProvider.state('validationStamp', {
            url: '/validationStamp/{validationStampId}',
            templateUrl: 'app/view/view.validationStamp.tpl.html',
            controller: 'ValidationStampCtrl'
        });
    })
    .controller('ValidationStampCtrl', function ($state, $scope, $stateParams, $http, ot, otStructureService, otAlertService, otGraphqlService) {
        const view = ot.view();
        let viewInitialised = false;
        // ValidationStamp's id
        const validationStampId = $stateParams.validationStampId;

        // Initial query parameters
        const queryVariables = {
            validationStampId: validationStampId,
            offset: 0,
            size: 20
        };

        // Query for the validation stamp
        const query = `
            query PaginatedValidationRuns($validationStampId: Int!, $offset: Int = 0, $size: Int = 20) {
                validationStamp(id: $validationStampId) {
                    id
                    name
                    description
                    image
                    _image
                    decorations {
                      decorationType
                      data
                      error
                      feature {
                        id
                      }
                    }
                    branch {
                      id
                      name
                      project {
                        id
                        name
                      }
                    }
                    links {
                      _self
                      _bulkUpdate
                      _update
                      _delete
                      _properties
                      _events
                    }
                    validationRunsPaginated(offset: $offset, size: $size) {
                      pageInfo {
                        totalSize
                        currentOffset
                        currentSize
                        previousPage {
                          offset
                          size
                        }
                        nextPage {
                          offset
                          size
                        }
                        pageIndex
                        pageTotal
                      }
                      pageItems {
                        id
                        runOrder
                        build {
                          name
                        }
                        validationRunStatuses {
                          statusID {
                            id
                            name
                          }
                          description
                          creation {
                            user
                            time
                          }
                        }
                      }
                    }
                }
            }`;

        // Loading the validation stamp
        function loadValidationStamp() {
            otGraphqlService.pageGraphQLCall(query, queryVariables).then(function (data) {
                const validationStamp = data.validationStamp;
                $scope.validationStamp = validationStamp;
                // View setup
                if (!viewInitialised) {
                    // View title
                    view.breadcrumbs = ot.branchBreadcrumbs(validationStamp.branch);
                    // Commands
                    view.commands = [
                        {
                            condition: function () {
                                return validationStamp.links._update;
                            },
                            id: 'updateValidationStampImage',
                            name: "Change image",
                            cls: 'ot-command-validation-stamp-image',
                            action: changeImage
                        },
                        {
                            condition: function () {
                                return validationStamp.links._update;
                            },
                            id: 'updateValidationStamp',
                            name: "Update validation stamp",
                            cls: 'ot-command-validation-stamp-update',
                            action: function () {
                                otStructureService.update(
                                    validationStamp.links._update,
                                    "Update validation stamp"
                                ).then(loadValidationStamp);
                            }
                        },
                        {
                            condition: function () {
                                return validationStamp.links._delete;
                            },
                            id: 'deleteValidationStamp',
                            name: "Delete validation stamp",
                            cls: 'ot-command-validation-stamp-delete',
                            action: function () {
                                otAlertService.confirm({
                                    title: "Deleting a validation stamp",
                                    message: "Do you really want to delete the validation stamp " + validationStamp.name +
                                    " and all its associated data?"
                                }).then(function () {
                                    return ot.call($http.delete(validationStamp.links._delete));
                                }).then(function () {
                                    $state.go('branch', {branchId: validationStamp.branch.id});
                                });
                            }
                        },
                        {
                            condition: function () {
                                return validationStamp.links._bulkUpdate;
                            },
                            id: 'bulkUpdateValidationStamp',
                            name: "Bulk update",
                            cls: 'ot-command-update',
                            action: function () {
                                otAlertService.confirm({
                                    title: "Validation stamps bulk update",
                                    message: "Updates all other validation stamps with the same name?"
                                }).then(function () {
                                    return ot.call($http.put(validationStamp.links._bulkUpdate, {}));
                                }).then(loadValidationStamp);
                            }
                        },
                        ot.viewApiCommand($scope.validationStamp.links._self),
                        ot.viewCloseCommand('/branch/' + $scope.validationStamp.branch.id)
                    ];
                    // View OK now
                    viewInitialised = true;
                }
            });
        }

        // Initialisation
        loadValidationStamp();

        // Changing the image
        function changeImage() {
            otStructureService.changeValidationStampImage($scope.validationStamp).then(loadValidationStamp);
        }

        // Switching the page
        $scope.switchPage = function (pageLink) {
            ot.pageCall($http.get(pageLink)).then(function (validationRunResources) {
                $scope.validationRunResources = validationRunResources;
            });
        };

    })
;<|endoftext|>


<commit_before>// -----------------------------------------------------------------------------------
// Copyright (c) Microsoft Open Technologies (Shanghai) Co. Ltd.  All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// -----------------------------------------------------------------------------------

;
(function($, w) {

    function FactoryAPI() {
        function API(obj, name) {
            var key;
            var getCmd = {};
            if (obj instanceof Array) {
                for (key in obj) {
                    getCmd[obj[key]] = API(obj[key], name)
                }
                return getCmd;
            } else if (obj instanceof Object) {
                for (key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        if (key == '') {
                            getCmd = API(obj[key], name)
                        } else {
                            getCmd[key] = API(obj[key], name + '/' + key);
                        }
                    }
                }
                return getCmd;
            } else {
                return getCmd[obj] = function(options, callback) {
                    var _params = {
                        query: null,
                        body: null,
                        header: {},
                    };
                    callback = callback || new Function();
                    if ($.isFunction(options)) {
                        callback = options;
                        options = {};
                    }
                    options = $.extend(_params, options);
                    var url = name;
                    var data = JSON.stringify(options.body);
                    if (options.query) {
                        url += '?' + ($.isPlainObject(options.query) ? $.param(options.query) : options.query);
                    }
                    options.header.token = $.cookie('token');
                    return $.ajax({
                        method: obj,
                        url: url,
                        contentType: obj == 'get' ? 'application/x-www-form-urlencoded' : 'application/json',
                        headers: options.header,
                        data: data,
                        success: function(data) {
                            if(data.error){
                                if(data.error.code == 401){
                                    location.href = '/logout';
                                }else {
                                    callback(data)
                                }
                            }else{
                                callback(data)
                            }
                        },
                        error: function(req, status, error) {
                            var data = {
                                error : {
                                    error: error ,
                                    message: req.responseText,
                                    status: req.status
                                }
                            };
                            callback(data);
                        }
                    });
                }
            }
        }
        return API(apiconfig.api, apiconfig.proxy + '/api');
    }

    var CURRENT_HACKATHON_COOKIE_NAME = 'current_hackathon';

    w.oh = w.oh || {};
    w.oh.api = FactoryAPI();
    w.oh.comm = {
        DateFormat: function(milliseconds, formatstr) {
            formatstr = formatstr || 'yyyy-MM-dd';
            return new Date(milliseconds).format(formatstr);
        },
        changeCurrentHackathon:function(hackathon){
            var data = {};
            data[$.cookie('token')] = hackathon;
            $.cookie(CURRENT_HACKATHON_COOKIE_NAME,JSON.stringify(data));
        },
        getCurrentHackathon: function() {
            var data = $.cookie(CURRENT_HACKATHON_COOKIE_NAME) || '{}';
            var token = $.cookie('token');
            var json = JSON.parse(data);
            if(json[token]){
                return json[token];
            }
            return  {name:'',id:0};
        },
        createLoading:function(elemt){
            $(elemt).children().hide();
            $(elemt).append($('

'))
        },
        removeLoading:function(){
            var pageloading = $('[data-type="pageloading"]')
            pageloading.siblings().show();
            pageloading.detach();
        }
    };

    $.getUrlParam = function(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    }

    function executeFunctionByName(functionName, context) {
        var args = [].slice.call(arguments).splice(2);
        var namespaces = functionName.split(".");
        var func = namespaces.pop();
        for (var i = 0; i < namespaces.length; i++) {
            context = context[namespaces[i]];
        }
        return context[func].apply(this, args);
    }

    window.addEventListener("storage", function(e) {
        var key = e.key;
        var newValue = e.newValue;
        var oldValue = e.oldValue;
        var url = e.url;
        var storageArea = e.storageArea;
        console.log(e);
    });

    function addTabsEvent(){
        var tabs = $('[data-type="tabs"]').on('click','a',function(e){
            e.preventDefault();
            var a = $(this);
            var toTab = a.attr('href');
            var li =  a.parent();
            li.addClass('active').siblings().removeClass('active');
            $(toTab).addClass('active').siblings().removeClass('active');;
        })
    }

    $(function() {
        w.oh.comm.createLoading('[loading]');
        addTabsEvent();
        var currentHackathon = w.oh.comm.getCurrentHackathon();
        $.template('switc_hackathons_temp', '
{{if id == $item.hid }}{{/if}}${name}
');
        $.template('switc_hackathons_temp2','
${name}
')
        var hackathon_modal = $('#switc_hackathon_modal').on('show.bs.modal', function(e) {
            var ul = hackathon_modal.find('.modal-body ul').empty();
            oh.api.admin.hackathon.list.get(function(data) {
                if(data.length >0){
                    ul.append($.tmpl('switc_hackathons_temp', data, {
                        hid: currentHackathon.id
                    }));
                }else if(location.pathname.search('createhackathon','i') == -1){
                    location.href = '/createhackathon';
                }
            });
        }).on('hide.bs.modal', function(e) {

        }).on('click', 'a[data-type="hackathon"]', function(e) {
            var li = $(this).parents('li');
            if (!li.hasClass('active')) {
                var data = li.data('tmplItem').data;
                w.oh.comm.changeCurrentHackathon({
                    name: data.name,
                    id: data.id
                });
                hackathon_modal.data({li: li});
                hackathon_modal.trigger('Reloadhackathon');
            }
        }).bind('Reloadhackathon', function(e) {
            var li = hackathon_modal.data('li');
            hackathon_modal.find('ul>li').removeClass('active');
            hackathon_modal.find('ul>li>i').detach();
            li.addClass('active').prepend('');
            location.reload()
        });

        if(location.pathname.length !=1 && location.pathname.search('createhackathon|login|logout','i') == -1){
            if(currentHackathon.id == 0){
                oh.api.admin.hackathon.list.get(function(data){
                    if(data.length == 0){
                        location.href = '/createhackathon';
                    }else if(data.length == 1){
                        w.oh.comm.changeCurrentHackathon({
                            name: data[0].name,
                            id: data[0].id
                        })
                    }else{
                        hackathon_modal.modal('show')
                    }
                })
            }else{
                 $('#content').prepend('<legend> 当前黑客松：'+currentHackathon.name+'</legend>')
            }
        }

        var menu = $('#sidebar-left .main-menu');
        menu.find('a').each(function() {
            if ($($(this))[0].href == String(window.location)) {
                $(this).parent().addClass('active');
                $(this).parents('ul').add(this).each(function() {
                    $(this).show();
                    $(this).prev('a').find('.chevron').removeClass('closed').addClass('opened')
                })
            }
        });

        menu.on('click', '.dropmenu', function(e) {
            e.preventDefault();
            var chevron = $(this).find('.chevron');
            if (chevron.hasClass('opened')) {
                chevron.removeClass('opened').addClass('closed');
                chevron.parents('li').find('ul').hide();
            } else {
                chevron.removeClass('closed').addClass('opened');
                chevron.parents('li').find('ul').show();
            }
        });

        function bindData(obj) {
            var _params = {
                header: {},
                body: {},
                query: {}
            }
            $.extend(_params, obj.data('options') || {});
            executeFunctionByName(obj.data('api'), w, _params, function(data) {
                obj.empty().append($(obj.data('target')).tmpl(data));
                if (obj.editable) {
                    obj.find('.edit').editable();
                }
                if (obj.data('change')) {
                    obj.trigger('oh.change');
                }
            });
        }

        $('[data-change]').bind('oh.change', function(e) {
            var obj = $(this);
            var tar = $(obj.data('change-target'));
            var data = {
                query: {},
                body: {}
            };
            data.query[tar.data('query')] = obj.val();
            tar.data({
                options: data
            });
            bindData(tar);
        }).change(function(e) {
            $(this).trigger('oh.change');
        });

        var confirm_modal = $('#confirm_modal').on('show.bs.modal', function(e) {
            confirm_modal
                .data({
                    item: $(e.relatedTarget).parents('tr').data('tmplItem').data,
                    target: $(e.relatedTarget).parents('tbody')
                });
        }).on('click', '[data-type="delete"]', function(e) {
            executeFunctionByName(confirm_modal.data('api'), w, {
                query: {
                    id: confirm_modal.data('item').id
                },
                header: {
                    hackathon_id: confirm_modal.data('item').hackathon_id
                }
            }, function(data) {
                bindData(confirm_modal.data('target'));
                confirm_modal.modal('hide');
            });
        });

        $('[data-toggle="bindtemp"]').each(function(i, o) {
            bindData($(o));
        });
    })
})(jQuery, window);
<commit_msg>update admin coer js<commit_after>// -----------------------------------------------------------------------------------
// Copyright (c) Microsoft Open Technologies (Shanghai) Co. Ltd.  All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// -----------------------------------------------------------------------------------

;
(function($, w) {

    function FactoryAPI() {
        function API(obj, name) {
            var key;
            var getCmd = {};
            if (obj instanceof Array) {
                for (key in obj) {
                    getCmd[obj[key]] = API(obj[key], name)
                }
                return getCmd;
            } else if (obj instanceof Object) {
                for (key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        if (key == '') {
                            getCmd = API(obj[key], name)
                        } else {
                            getCmd[key] = API(obj[key], name + '/' + key);
                        }
                    }
                }
                return getCmd;
            } else {
                return getCmd[obj] = function(options, callback) {
                    var _params = {
                        query: null,
                        body: null,
                        header: {},
                    };
                    callback = callback || new Function();
                    if ($.isFunction(options)) {
                        callback = options;
                        options = {};
                    }
                    options = $.extend(_params, options);
                    var url = name;
                    var data = JSON.stringify(options.body);
                    if (options.query) {
                        url += '?' + ($.isPlainObject(options.query) ? $.param(options.query) : options.query);
                    }
                    options.header.token = $.cookie('token');
                    return $.ajax({
                        method: obj,
                        url: url,
                        contentType: obj == 'get' ? 'application/x-www-form-urlencoded' : 'application/json',
                        headers: options.header,
                        data: data,
                        success: function(data) {
                            if(data.error){
                                if(data.error.code == 401){
                                    location.href = '/logout';
                                }else {
                                    callback(data)
                                }
                            }else{
                                callback(data)
                            }
                        },
                        error: function(req, status, error) {
                            var data = {
                                error : {
                                    error: error ,
                                    message: req.responseText,
                                    status: req.status
                                }
                            };
                            callback(data);
                        }
                    });
                }
            }
        }
        return API(apiconfig.api, apiconfig.proxy + '/api');
    }

    var CURRENT_HACKATHON_COOKIE_NAME = 'current_hackathon';

    w.oh = w.oh || {};
    w.oh.api = FactoryAPI();
    w.oh.comm = {
        DateFormat: function(milliseconds, formatstr) {
            formatstr = formatstr || 'yyyy-MM-dd';
            return new Date(milliseconds).format(formatstr);
        },
        changeCurrentHackathon:function(hackathon){
            var data = {};
            data[$.cookie('token')] = hackathon;
            $.cookie(CURRENT_HACKATHON_COOKIE_NAME,JSON.stringify(data));
        },
        getCurrentHackathon: function() {
            var data = $.cookie(CURRENT_HACKATHON_COOKIE_NAME) || '{}';
            var token = $.cookie('token');
            var json = JSON.parse(data);
            if(json[token]){
                return json[token];
            }
            return  {name:'',id:0};
        },
        createLoading:function(elemt){
            $(elemt).children().hide();
            $(elemt).append($('

'))
        },
        removeLoading:function(){
            var pageloading = $('[data-type="pageloading"]')
            pageloading.siblings().show();
            pageloading.detach();
        }
    };

    $.getUrlParam = function(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    }

    function executeFunctionByName(functionName, context) {
        var args = [].slice.call(arguments).splice(2);
        var namespaces = functionName.split(".");
        var func = namespaces.pop();
        for (var i = 0; i < namespaces.length; i++) {
            context = context[namespaces[i]];
        }
        return context[func].apply(this, args);
    }

    window.addEventListener("storage", function(e) {
        var key = e.key;
        var newValue = e.newValue;
        var oldValue = e.oldValue;
        var url = e.url;
        var storageArea = e.storageArea;
        console.log(e);
    });

    function addTabsEvent(){
        var tabs = $('[data-type="tabs"]').on('click','a',function(e){
            e.preventDefault();
            var a = $(this);
            var toTab = a.attr('href');
            var li =  a.parent();
            li.addClass('active').siblings().removeClass('active');
            $(toTab).addClass('active').siblings().removeClass('active');;
        })
    }

    $(function() {
        if(location.pathname.search('logout','i') != -1){
            location.href = '/login';
            return;
        }
        w.oh.comm.createLoading('[loading]');
        addTabsEvent();
        var currentHackathon = w.oh.comm.getCurrentHackathon();
        $.template('switc_hackathons_temp', '
{{if id == $item.hid }}{{/if}}${name}
');
        $.template('switc_hackathons_temp2','
${name}
')
        var hackathon_modal = $('#switc_hackathon_modal').on('show.bs.modal', function(e) {
            var ul = hackathon_modal.find('.modal-body ul').empty();
            oh.api.admin.hackathon.list.get(function(data) {
                if(data.length >0){
                    ul.append($.tmpl('switc_hackathons_temp', data, {
                        hid: currentHackathon.id
                    }));
                }else if(location.pathname.search('createhackathon','i') == -1){
                    location.href = '/createhackathon';
                }
            });
        }).on('hide.bs.modal', function(e) {

        }).on('click', 'a[data-type="hackathon"]', function(e) {
            var li = $(this).parents('li');
            if (!li.hasClass('active')) {
                var data = li.data('tmplItem').data;
                w.oh.comm.changeCurrentHackathon({
                    name: data.name,
                    id: data.id
                });
                hackathon_modal.data({li: li});
                hackathon_modal.trigger('Reloadhackathon');
            }
        }).bind('Reloadhackathon', function(e) {
            var li = hackathon_modal.data('li');
            hackathon_modal.find('ul>li').removeClass('active');
            hackathon_modal.find('ul>li>i').detach();
            li.addClass('active').prepend('');
            location.reload()
        });

        if(location.pathname.length !=1 && location.pathname.search('createhackathon|login|logout','i') == -1){
            if(currentHackathon.id == 0){
                oh.api.admin.hackathon.list.get(function(data){
                    if(data.length == 0){
                        location.href = '/createhackathon';
                    }else if(data.length == 1){
                        w.oh.comm.changeCurrentHackathon({
                            name: data[0].name,
                            id: data[0].id
                        })
                    }else{
                        hackathon_modal.modal('show')
                    }
                })
            }else{
                 $('#content').prepend('<legend> 当前黑客松：'+currentHackathon.name+'</legend>')
            }
        }

        var menu = $('#sidebar-left .main-menu');
        menu.find('a').each(function() {
            if ($($(this))[0].href == String(window.location)) {
                $(this).parent().addClass('active');
                $(this).parents('ul').add(this).each(function() {
                    $(this).show();
                    $(this).prev('a').find('.chevron').removeClass('closed').addClass('opened')
                })
            }
        });

        menu.on('click', '.dropmenu', function(e) {
            e.preventDefault();
            var chevron = $(this).find('.chevron');
            if (chevron.hasClass('opened')) {
                chevron.removeClass('opened').addClass('closed');
                chevron.parents('li').find('ul').hide();
            } else {
                chevron.removeClass('closed').addClass('opened');
                chevron.parents('li').find('ul').show();
            }
        });

        function bindData(obj) {
            var _params = {
                header: {},
                body: {},
                query: {}
            }
            $.extend(_params, obj.data('options') || {});
            executeFunctionByName(obj.data('api'), w, _params, function(data) {
                obj.empty().append($(obj.data('target')).tmpl(data));
                if (obj.editable) {
                    obj.find('.edit').editable();
                }
                if (obj.data('change')) {
                    obj.trigger('oh.change');
                }
            });
        }

        $('[data-change]').bind('oh.change', function(e) {
            var obj = $(this);
            var tar = $(obj.data('change-target'));
            var data = {
                query: {},
                body: {}
            };
            data.query[tar.data('query')] = obj.val();
            tar.data({
                options: data
            });
            bindData(tar);
        }).change(function(e) {
            $(this).trigger('oh.change');
        });

        var confirm_modal = $('#confirm_modal').on('show.bs.modal', function(e) {
            confirm_modal
                .data({
                    item: $(e.relatedTarget).parents('tr').data('tmplItem').data,
                    target: $(e.relatedTarget).parents('tbody')
                });
        }).on('click', '[data-type="delete"]', function(e) {
            executeFunctionByName(confirm_modal.data('api'), w, {
                query: {
                    id: confirm_modal.data('item').id
                },
                header: {
                    hackathon_id: confirm_modal.data('item').hackathon_id
                }
            }, function(data) {
                bindData(confirm_modal.data('target'));
                confirm_modal.modal('hide');
            });
        });

        $('[data-toggle="bindtemp"]').each(function(i, o) {
            bindData($(o));
        });
    })
})(jQuery, window);
<|endoftext|>


<commit_before>/*
 #
 # Copyright (c) 2017 nexB Inc. and others. All rights reserved.
 # http://nexb.com and https://github.com/nexB/scancode-toolkit/
 # The ScanCode software is licensed under the Apache License version 2.0.
 # AboutCode is a trademark of nexB Inc.
 #
 # You may not use this software except in compliance with the License.
 # You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
 # Unless required by applicable law or agreed to in writing, software distributed
 # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 # CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 #
 */

// Load nedb and create an in-memory database
var Sequelize = require("sequelize");

// Creates a new database on the flattened json data
function AboutCodeDB(json, callback) {

    // Constructor returns an object which effectively represents a connection
    // to the db arguments (name of db, username for db, pw for that user)
    var connection = new Sequelize("demo_schema", "root", "password", {
        dialect: "sqlite"
    });

    // Defines columns in the scanned file table
    this.ScannedFile = AboutCodeDB.defineScannedFile(connection);

    // A promise that will return when the db and tables have been created
    this.dbPromise = connection.sync();

    if (json) {

        var that = this;

        // Add all rows to the DB, then call the callback
        this.dbPromise.then(function() {
            $.each(json.files, function(i, file) {
                that.ScannedFile.create(AboutCodeDB.flattenData(file));
            });
        })
        .then(callback);
    }
}

module.exports = AboutCodeDB;

/**
 * AboutCodeDB data instance functions.
 *
 * Each new AboutCodeDB() has its own 'this' variable.
 */

AboutCodeDB.prototype = {

    // This function is called every time DataTables needs to be redrawn.
    // For details on the parameters https://datatables.net/manual/server-side
    query: function (dataTablesInput, dataTablesCallback) {
        console.log("Querying DB");
        var that = this;

        // TODO: Sorting of DataTable
        this.dbPromise.then(function() {

            // query = {
            //   where: {
            //     $and: {
            //       path: { $like: 'columnSearch%' },
            //       $or: [
            //         { path: { $like: 'globalSearch%' } },
            //         { copyright_statements: { $like: 'globalSearch%' } },
            //         ...,
            //       ]
            //     }
            //   }
            // }
            var query = {
                where: {
                    $and: {}
                }
            };

            // If a column search exists, add search for that column
            for (var i = 0; i < dataTablesInput.columns.length; i++) {
                var columnSearch = dataTablesInput.columns[i].search.value;
                if (columnSearch) {
                    query.where.$and[dataTablesInput.columns[i].name] = {
                        $like: columnSearch + '%'
                    }
                }
            }

            // If a global search exists, add an $or search for each column
            var globalSearch = dataTablesInput.search.value;
            if (globalSearch) {
                query.where.$and.$or = [];
                for (var i = 0; i < dataTablesInput.columns.length; i++) {
                    var orSearch = {};
                    orSearch[dataTablesInput.columns[i].name] = {
                        $like: globalSearch + '%'
                    };
                    query.where.$and.$or.push(orSearch);
                }
            }

            // Execute the database find to get the rows of data
            that.ScannedFile.findAndCountAll(query)
                .then(function(result) {
                    if (result && result.rows) {
//                       console.log(result.rows)
                       dataTablesCallback({
                           draw: dataTablesInput.draw,
                           data: result.rows,
                           recordsFiltered: result.count,
                           recordsTotal: result.count
                       });
                    }
                console.log("Query Finished");
            });
        });
    }
}

/**
 * AboutCodeDB data class functions.
 *
 * These functions do not have 'this' variables.
 */

// Defines a table for a flattened scanned file
AboutCodeDB.defineScannedFile = function(connection) {

    // DB COLUMN TYPE: A string with empty string default value
    function getDefaultStringType() {
        return {
            type: Sequelize.STRING,
            defaultValue: ""
        };
    }

    return connection.define("file", {
        path: Sequelize.STRING,
        copyright_statements: getDefaultStringType(),
        copyright_holders: getDefaultStringType(),
        copyright_authors: getDefaultStringType(),
        copyright_start_line: getDefaultStringType(),
        copyright_end_line:  getDefaultStringType(),
        license_key: getDefaultStringType(),
        license_score:  getDefaultStringType(),
        license_short_name: getDefaultStringType(),
        license_category: getDefaultStringType(),
        license_owner: getDefaultStringType(),
        license_homepage_url: getDefaultStringType(),
        license_text_url: getDefaultStringType(),
        license_djc_url: getDefaultStringType(),
        license_spdx_key: getDefaultStringType(),
        license_start_line:  getDefaultStringType(),
        license_end_line:  getDefaultStringType(),
        email: getDefaultStringType(),
        email_start_line:  getDefaultStringType(),
        email_end_line:  getDefaultStringType(),
        url: getDefaultStringType(),
        url_start_line: getDefaultStringType(),
        url_end_line: getDefaultStringType(),
        infos_type: getDefaultStringType(),
        infos_file_name: getDefaultStringType(),
        infos_file_extension: getDefaultStringType(),
        infos_file_date: getDefaultStringType(),
        infos_file_size: getDefaultStringType(),
        infos_file_sha1: getDefaultStringType(),
        infos_md5: getDefaultStringType(),
        infos_file_count: getDefaultStringType(),
        infos_mime_type: getDefaultStringType(),
        infos_file_type: getDefaultStringType(),
        infos_programming_language: getDefaultStringType(),
        infos_is_binary:  getDefaultStringType(),
        infos_is_text: getDefaultStringType(),
        infos_is_archive:  getDefaultStringType(),
        infos_is_media: getDefaultStringType(),
        infos_is_source: getDefaultStringType(),
        infos_is_script: getDefaultStringType(),
        packages_type: getDefaultStringType(),
        packages_packaging: getDefaultStringType(),
        packages_primary_language: getDefaultStringType()
    });
}

// Flatten ScanCode results data to load into database
AboutCodeDB.flattenData = function (file) {
    return {
        path: file.path,
        copyright_statements: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'statements'),
        copyright_holders: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'holders'),
        copyright_authors: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'authors'),
        copyright_start_line: AboutCodeDB.flattenArray(file.copyrights, 'start_line'),
        copyright_end_line: AboutCodeDB.flattenArray(file.copyrights, 'end_line'),
        license_key: AboutCodeDB.flattenArray(file.licenses, 'key'),
        license_score: AboutCodeDB.flattenArray(file.licenses, 'score'),
        license_short_name: AboutCodeDB.flattenArray(file.licenses, 'short_name'),
        license_category: AboutCodeDB.flattenArray(file.licenses, 'category'),
        license_owner: AboutCodeDB.flattenArray(file.licenses, 'party'),
        license_homepage_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'homepage_url'),
        license_text_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'text_url'),
        license_djc_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'dejacode_url'),
        license_spdx_key: AboutCodeDB.flattenArray(file.licenses, 'spdx_license_key'),
        license_start_line: AboutCodeDB.flattenArray(file.licenses, 'start_line'),
        license_end_line: AboutCodeDB.flattenArray(file.licenses, 'end_line'),
        email: AboutCodeDB.flattenArray(file.emails, 'email'),
        email_start_line: AboutCodeDB.flattenArray(file.emails, 'start_line'),
        email_end_line: AboutCodeDB.flattenArray(file.emails, 'end_line'),
        url: AboutCodeDB.flattenArrayOfUrl(file.urls, 'url'),
        url_start_line: AboutCodeDB.flattenArrayOfUrlLine(file.urls, 'start_line'),
        url_end_line: AboutCodeDB.flattenArrayOfUrlLine(file.urls, 'end_line'),
        infos_type: file.type,
        infos_file_name: file.name,
        infos_file_extension: file.extension,
        infos_file_date: file.date,
        infos_file_size: file.size,
        infos_file_sha1: file.sha1,
        infos_md5: file.md5,
        infos_file_count: file.files_count,
        infos_mime_type: file.mime_type,
        infos_file_type: file.file_type,
        infos_programming_language: file.programming_language,
        infos_is_binary: file.is_binary,
        infos_is_text: file.is_text,
        infos_is_archive: file.is_archive,
        infos_is_media: file.is_media,
        infos_is_source: file.is_source,
        infos_is_script: file.is_script,
        packages_type: AboutCodeDB.flattenArray(file.packages, 'type'),
        packages_packaging: AboutCodeDB.flattenArray(file.packages, 'packaging'),
        packages_primary_language: AboutCodeDB.flattenArray(file.packages, 'primary_language')
    }
}

// array: [
//     {key: [val0, val1]},
//     {key: [val2, val3]},
// ]
// => 'val0
val1
val2
val3'
AboutCodeDB.flattenArrayOfArray = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key].join("
") : [];
    }).join("
");
}

// array: [
//     {key: val0},
//     {key: val1},
// ]
// => 'val0
val1'
AboutCodeDB.flattenArray = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key] : [];
    }).join("
");
}

// array: [
//     {key: val0},
//     {key: val1},
// ]
// => 'val0
val1'
AboutCodeDB.flattenArrayOfUrlLine = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key] : [];
    }).join("
");
}

// array: [
//     {key: url0},
//     {key: url1},
// ]
// => 'url0

//     url1'
AboutCodeDB.flattenArrayOfUrl = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        var href = elem[key];

        return ''+href+'';
    }).join("
");
}<commit_msg>#31: Added sorting, offset, and limit with DataTables * Works with DT single-column sorting * Added limit and offset to Sequelize DB * Fixed the DataTables filtered count<commit_after>/*
 #
 # Copyright (c) 2017 nexB Inc. and others. All rights reserved.
 # http://nexb.com and https://github.com/nexB/scancode-toolkit/
 # The ScanCode software is licensed under the Apache License version 2.0.
 # AboutCode is a trademark of nexB Inc.
 #
 # You may not use this software except in compliance with the License.
 # You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
 # Unless required by applicable law or agreed to in writing, software distributed
 # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 # CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 #
 */

// Load nedb and create an in-memory database
var Sequelize = require("sequelize");

// Creates a new database on the flattened json data
function AboutCodeDB(json, callback) {

    // Constructor returns an object which effectively represents a connection
    // to the db arguments (name of db, username for db, pw for that user)
    var connection = new Sequelize("demo_schema", "root", "password", {
        dialect: "sqlite"
    });

    // Defines columns in the scanned file table
    this.ScannedFile = AboutCodeDB.defineScannedFile(connection);

    // A promise that will return when the db and tables have been created
    this.dbPromise = connection.sync();

    if (json) {

        var that = this;

        // Add all rows to the DB, then call the callback
        this.dbPromise.then(function() {
            var flattenedFiles = $.map(json.files, function(file, index) {
                return AboutCodeDB.flattenData(file);
            });
            return that.ScannedFile.bulkCreate(flattenedFiles);
        }).then(callback);
    }
}

module.exports = AboutCodeDB;

/**
 * AboutCodeDB data instance functions.
 *
 * Each new AboutCodeDB() has its own 'this' variable.
 */

AboutCodeDB.prototype = {

    // This function is called every time DataTables needs to be redrawn.
    // For details on the parameters https://datatables.net/manual/server-side
    query: function (dataTablesInput, dataTablesCallback) {
        var that = this;

        // Sorting and Querying of data for DataTables
        this.dbPromise.then(function() {
            var columnIndex = dataTablesInput.order[0].column;
            var columnName = dataTablesInput.columns[columnIndex].name;
            var direction = dataTablesInput.order[0].dir === 'desc' ? "DESC" : "ASC";

            // query = {
            //   where: {
            //     $and: {
            //       path: { $like: 'columnSearch%' },
            //       $or: [
            //         { path: { $like: 'globalSearch%' } },
            //         { copyright_statements: { $like: 'globalSearch%' } },
            //         ...,
            //       ]
            //     }
            //   }
            // }
            var query = {
                where: {
                    $and: {}
                },
                // Only take the chunk of data DataTables needs
                limit: dataTablesInput.length,
                offset: dataTablesInput.start,
                order: [[columnName, direction]]
            };

            // If a column search exists, add search for that column
            for (var i = 0; i < dataTablesInput.columns.length; i++) {
                var columnSearch = dataTablesInput.columns[i].search.value;
                if (columnSearch) {
                    query.where.$and[dataTablesInput.columns[i].name] = {
                        $like: columnSearch + '%'
                    }
                }
            }

            // If a global search exists, add an $or search for each column
            var globalSearch = dataTablesInput.search.value;
            if (globalSearch) {
                query.where.$and.$or = [];
                for (var i = 0; i < dataTablesInput.columns.length; i++) {
                    var orSearch = {};
                    orSearch[dataTablesInput.columns[i].name] = {
                        $like: globalSearch + '%'
                    };
                    query.where.$and.$or.push(orSearch);
                }
            }

            // Execute the database find to get the rows of data
            var dFind = $.Deferred();
            that.ScannedFile.findAll(query)
                .then(function(result) {
                    dFind.resolve(result);
                });

            // Execute the database count of all rows
            var dCount = $.Deferred();
            that.ScannedFile.count({})
                .then(function(count) {
                    dCount.resolve(count);
                });

            // Execute the database count of filtered query rows
            var dFilteredCount = $.Deferred();
            that.ScannedFile.count(query)
                .then(function(count) {
                    dFilteredCount.resolve(count);
                })

            // Wait for all three of the Deferred objects to finish
            $.when(dFind, dCount, dFilteredCount)
                .then(function (rows, count, filteredCount) {
                    dataTablesCallback({
                       draw: dataTablesInput.draw,
                       data: rows ? rows : [],
                       recordsFiltered: filteredCount,
                       recordsTotal: count
                    });
                });
        });
    }
}

/**
 * AboutCodeDB data class functions.
 *
 * These functions do not have 'this' variables.
 */

// Defines a table for a flattened scanned file
AboutCodeDB.defineScannedFile = function(connection) {

    // DB COLUMN TYPE: A string with empty string default value
    function getDefaultStringType() {
        return {
            type: Sequelize.STRING,
            defaultValue: ""
        };
    }

    return connection.define("file", {
        path: {
            type: Sequelize.STRING,
            unique: true,
            allowNull: false
        },
        copyright_statements: getDefaultStringType(),
        copyright_holders: getDefaultStringType(),
        copyright_authors: getDefaultStringType(),
        copyright_start_line: getDefaultStringType(),
        copyright_end_line:  getDefaultStringType(),
        license_key: getDefaultStringType(),
        license_score:  getDefaultStringType(),
        license_short_name: getDefaultStringType(),
        license_category: getDefaultStringType(),
        license_owner: getDefaultStringType(),
        license_homepage_url: getDefaultStringType(),
        license_text_url: getDefaultStringType(),
        license_djc_url: getDefaultStringType(),
        license_spdx_key: getDefaultStringType(),
        license_start_line:  getDefaultStringType(),
        license_end_line:  getDefaultStringType(),
        email: getDefaultStringType(),
        email_start_line:  getDefaultStringType(),
        email_end_line:  getDefaultStringType(),
        url: getDefaultStringType(),
        url_start_line: getDefaultStringType(),
        url_end_line: getDefaultStringType(),
        infos_type: getDefaultStringType(),
        infos_file_name: getDefaultStringType(),
        infos_file_extension: getDefaultStringType(),
        infos_file_date: getDefaultStringType(),
        infos_file_size: getDefaultStringType(),
        infos_file_sha1: getDefaultStringType(),
        infos_md5: getDefaultStringType(),
        infos_file_count: getDefaultStringType(),
        infos_mime_type: getDefaultStringType(),
        infos_file_type: getDefaultStringType(),
        infos_programming_language: getDefaultStringType(),
        infos_is_binary:  getDefaultStringType(),
        infos_is_text: getDefaultStringType(),
        infos_is_archive:  getDefaultStringType(),
        infos_is_media: getDefaultStringType(),
        infos_is_source: getDefaultStringType(),
        infos_is_script: getDefaultStringType(),
        packages_type: getDefaultStringType(),
        packages_packaging: getDefaultStringType(),
        packages_primary_language: getDefaultStringType()
    }, {
        indexes: [
            // Create a unique index on path
            {
                unique: true,
                fields: ['path']
            }
        ]
    });
}

// Flatten ScanCode results data to load into database
AboutCodeDB.flattenData = function (file) {
    return {
        path: file.path,
        copyright_statements: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'statements'),
        copyright_holders: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'holders'),
        copyright_authors: AboutCodeDB.flattenArrayOfArray(file.copyrights, 'authors'),
        copyright_start_line: AboutCodeDB.flattenArray(file.copyrights, 'start_line'),
        copyright_end_line: AboutCodeDB.flattenArray(file.copyrights, 'end_line'),
        license_key: AboutCodeDB.flattenArray(file.licenses, 'key'),
        license_score: AboutCodeDB.flattenArray(file.licenses, 'score'),
        license_short_name: AboutCodeDB.flattenArray(file.licenses, 'short_name'),
        license_category: AboutCodeDB.flattenArray(file.licenses, 'category'),
        license_owner: AboutCodeDB.flattenArray(file.licenses, 'party'),
        license_homepage_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'homepage_url'),
        license_text_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'text_url'),
        license_djc_url: AboutCodeDB.flattenArrayOfUrl(file.licenses, 'dejacode_url'),
        license_spdx_key: AboutCodeDB.flattenArray(file.licenses, 'spdx_license_key'),
        license_start_line: AboutCodeDB.flattenArray(file.licenses, 'start_line'),
        license_end_line: AboutCodeDB.flattenArray(file.licenses, 'end_line'),
        email: AboutCodeDB.flattenArray(file.emails, 'email'),
        email_start_line: AboutCodeDB.flattenArray(file.emails, 'start_line'),
        email_end_line: AboutCodeDB.flattenArray(file.emails, 'end_line'),
        url: AboutCodeDB.flattenArrayOfUrl(file.urls, 'url'),
        url_start_line: AboutCodeDB.flattenArrayOfUrlLine(file.urls, 'start_line'),
        url_end_line: AboutCodeDB.flattenArrayOfUrlLine(file.urls, 'end_line'),
        infos_type: file.type,
        infos_file_name: file.name,
        infos_file_extension: file.extension,
        infos_file_date: file.date,
        infos_file_size: file.size,
        infos_file_sha1: file.sha1,
        infos_md5: file.md5,
        infos_file_count: file.files_count,
        infos_mime_type: file.mime_type,
        infos_file_type: file.file_type,
        infos_programming_language: file.programming_language,
        infos_is_binary: file.is_binary,
        infos_is_text: file.is_text,
        infos_is_archive: file.is_archive,
        infos_is_media: file.is_media,
        infos_is_source: file.is_source,
        infos_is_script: file.is_script,
        packages_type: AboutCodeDB.flattenArray(file.packages, 'type'),
        packages_packaging: AboutCodeDB.flattenArray(file.packages, 'packaging'),
        packages_primary_language: AboutCodeDB.flattenArray(file.packages, 'primary_language')
    }
}

// array: [
//     {key: [val0, val1]},
//     {key: [val2, val3]},
// ]
// => 'val0
val1
val2
val3'
AboutCodeDB.flattenArrayOfArray = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key].join("
") : [];
    }).join("
");
}

// array: [
//     {key: val0},
//     {key: val1},
// ]
// => 'val0
val1'
AboutCodeDB.flattenArray = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key] : [];
    }).join("
");
}

// array: [
//     {key: val0},
//     {key: val1},
// ]
// => 'val0
val1'
AboutCodeDB.flattenArrayOfUrlLine = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        return elem[key] ? elem[key] : [];
    }).join("
");
}

// array: [
//     {key: url0},
//     {key: url1},
// ]
// => 'url0

//     url1'
AboutCodeDB.flattenArrayOfUrl = function (array, key) {
    return $.map(array ? array : [], function (elem, i) {
        var href = elem[key];

        return ''+href+'';
    }).join("
");
}<|endoftext|>