function validateProjectionOnTableHandler()

in database-jones/Adapter/api/UserContext.js [1029:1140]


  function validateProjectionOnTableHandler(err, dbTableHandler) {
    // currently validating projections[index] with the tableHandler for the domain object
    projection = projections[index];
    // keep track of how many times this projection has been changed so adapters know when to re-validate
    projection.id = (projection.id + 1) % (2^24);
    projection.childProjections = [];
    
    domainObject = projection.domainObject;
    domainObjectName = domainObject.prototype.constructor.name;
    domainObjectMynode = domainObject.prototype.jones;
    if (domainObjectMynode && domainObjectMynode.mapping.error) {
      // remember errors in mapping
      errors += domainObjectMynode.mapping.error;
    }
    if (!err) {
      projection.dbTableHandler = dbTableHandler;
      // validate projected fields against columns using table handler
      if (typeof domainObject === 'function' &&
          typeof domainObject.prototype.jones === 'object' &&
          typeof domainObject.prototype.jones.mapping === 'object') {
        projection.mapping = domainObject.prototype.jones.mapping;
        // good domainObject; have we seen this one before?
        mappingId = domainObject.prototype.jones.mappingId;
        if (mappingIds.indexOf(mappingId) === -1) {
          // have not seen this one before; add its mappingId to list of mappingIds to prevent cycles (recursion)
          mappingIds.push(mappingId);
          // validate all fields in projection are mapped
          if (projection.fields) { // field names
            projection.fields.forEach(function(fieldName) {
              fieldMapping = dbTableHandler.getFieldMapping(fieldName);
              if (fieldMapping) {
                if (fieldMapping.relationship) {
                  errors += '\nBad projection for ' +  domainObjectName + ': field' + fieldName +
                      ' must not be a relationship';
                }
              } else {
                // error: fields must be mapped
                errors += '\nBad projection for ' +  domainObjectName + ': field ' + fieldName + ' is not mapped';
              }
            });
          }
          // validate all relationships in mapping regardless of whether they are in this projection
          
          dbTableHandler.relationshipFields.forEach(function(relationshipField) {
            // get the name and projection for each relationship
            foreignKeyName = relationshipField.foreignKey;
            if (foreignKeyName) {
              // make sure the foreign key exists
              if (!dbTableHandler.getForeignKey(foreignKeyName)) {
                errors += '\nBad relationship field mapping; foreign key ' + foreignKeyName +
                    ' does not exist in table; possible foreign keys are: ' + dbTableHandler.getForeignKeyNames();
              }
            }
            // remember this relationship in order to resolve table mapping for join table
            if (relationshipField.joinTable) {
              joinTableRelationshipFields.push(relationshipField);
            }
          });
          // add relationship domain objects to the list of domain objects
          relationships = projection.relationships;
          if (relationships) {
            Object.keys(relationships).forEach(function(key) {
              // each key is the name of a relationship that must be a field in the table handler
              fieldMapping = dbTableHandler.getFieldMapping(key);
              if (fieldMapping) {
                if (fieldMapping.relationship) {
                  childProjection = relationships[key];
                  if (childProjection.parentProjection && childProjection.parentProjection !== projection) {
                    // this child projection is already being used by a different projection
                    errors += '\nBad relationship for ' +  domainObjectName + ': field ' + key +
                        ' of type ' + childProjection.domainObject.name +
                        ' is already in use by a different projection.';
                  } else {
                    childProjection.parentTableHandler = dbTableHandler;
                    childProjection.parentFieldMapping = fieldMapping;
                    childProjection.parentProjection = projection;
                    // add each relationship to the current list of projections to be validated
                    projections.push(childProjection);
                    projection.childProjections.push(childProjection);
                  }
                } else {
                  // error: field is not a relationship
                  errors += '\nBad relationship for ' +  domainObjectName + ': field ' + key +
                      ' is not a relationship.';
                }
              } else {
                // error: relationships must be mapped
                errors += '\nBad relationship for ' +  domainObjectName + ': relationship ' + key + ' is not mapped.';
              }
            });
          }
        } else {
          // recursive projection
          errors += '\nRecursive projection for ' + domainObjectName;
        }
      } else {
        // domainObject was not mapped
        errors += '\nBad domain object: ' + domainObjectName + ' is not mapped.';
      } 
    } else {
      // table does not exist
        errors += '\nUnable to acquire tableHandler for ' + domainObjectName + ' : ' + err.message;
    }
    // finished validating this projection; do we have a join table to validate?
    if (joinTableRelationshipFields.length > 0) {
      // get the table handler for the first join table
      joinTableRelationshipField = joinTableRelationshipFields.shift();
      getTableHandler(userContext, joinTableRelationshipField.joinTable, session, validateJoinTableOnTableHandler);
    } else {
      continueValidation();
    }
  }