text: // Generated by CoffeeScript 1.6.3
  (function() {
    var SchemaDefinition, clone;
  
    clone = require('clone');
  
    SchemaDefinition = (function() {
      function SchemaDefinition(source) {
        this._validate(source);
        this._processSource(source);
      }
  
      SchemaDefinition.prototype._validate = function(source) {
        var entity, entityName, _results;
        _results = [];
        for (entityName in source) {
          entity = source[entityName];
          if (!entity.columns && (!entity.relations || !entity.relationships)) {
            throw new Error('not a valid definition source');
          } else {
            _results.push(void 0);
          }
        }
        return _results;
      };
  
      SchemaDefinition.prototype._processSource = function(sourceOrigin) {
        var column, columnName, entitiesByName, entity, entityName, index, indexName, relation, relationName, relations, relationsByName, source, _entity, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4, _relation, _results;
        source = clone(sourceOrigin);
        entitiesByName = {};
        this.entities = [];
        for (entityName in source) {
          entity = source[entityName];
          _entity = {
            name: entityName
          };
          _entity.columns = [];
          _ref = entity.columns;
          for (columnName in _ref) {
            column = _ref[columnName];
            if (typeof column === 'string') {
              column = {
                type: column
              };
            }
            column.name = columnName;
            _entity.columns.push(column);
          }
          _entity.relations = [];
          relations = entity.relations || entity.relationships;
          relationsByName = {};
          for (relationName in relations) {
            relation = relations[relationName];
            relation.name = relationName;
            _entity.relations.push(relation);
            relationsByName[relationName] = relation;
          }
          _entity.indexes = [];
          _ref1 = entity.indexes;
          for (indexName in _ref1) {
            index = _ref1[indexName];
            if (typeof index === 'string') {
              index = {
                columns: index
              };
            }
            index.name = indexName;
            _entity.indexes.push(index);
          }
          this.entities.push(_entity);
          entitiesByName[entityName] = _entity;
        }
        _ref2 = this.entities;
        _results = [];
        for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
          entity = _ref2[_i];
          _ref3 = entity.relations;
          for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
            relation = _ref3[_j];
            if (relation.inverse) {
              relation.entity = entitiesByName[relation.entity];
              relation.inverseName = relation.inverse;
              relation.inverse = null;
              _ref4 = relation.entity.relations;
              for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
                _relation = _ref4[_k];
                if (_relation.name === relation.inverseName) {
                  relation.inverse = _relation;
                }
              }
              if (!relation.inverse && !relation.type) {
                throw new Error('inverse relation not found ' + entity.name + '=>' + relation.name + '(' + relation.inverseName + ')');
              }
              if (relation.toMany && relation.inverse.toMany) {
                relation.primary = relation.entity.name < relation.inverse.entity.name;
                relation.inverse.primary = !relation.primary;
              }
            }
            switch (relation.type) {
              case 'manyToOne':
                relation.toMany = false;
                break;
              case 'oneToMany':
                relation.toMany = true;
                if (!relation.inverse) {
                  relation.inverse = {
                    name: relation.inverseName,
                    toMany: false,
                    entity: entity
                  };
                  relation.entity.relations.push(relation.inverse);
                }
                break;
              case 'manyToMany':
                relation.toMany = true;
                relation.primary = true;
                if (!relation.inverse) {
                  relation.inverse = {
                    name: relation.inverseName,
                    toMany: true,
                    entity: entity
                  };
                  relation.entity.relations.push(relation.inverse);
                }
            }
          }
          _results.push((function() {
            var _l, _len3, _ref5, _results1;
            _ref5 = entity.indexes;
            _results1 = [];
            for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
              index = _ref5[_l];
              if (typeof index.columns === 'string') {
                index.columns = index.columns.split(',');
              }
              index.columns = index.columns || [];
              if (index.column) {
                _results1.push(index.columns.push(index.column));
              } else {
                _results1.push(void 0);
              }
            }
            return _results1;
          })());
        }
        return _results;
      };
  
      SchemaDefinition.prototype.getEntity = function(name) {
        var entity, _i, _len, _ref;
        _ref = this.entities;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          entity = _ref[_i];
          if (entity.name === name) {
            return entity;
          }
        }
      };
  
      SchemaDefinition.prototype.getColumn = function(entityName, columnName) {
        var column, _i, _len, _ref;
        _ref = this.getEntity(entityName).columns;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          column = _ref[_i];
          if (column.name === columnName) {
            return column;
          }
        }
      };
  
      SchemaDefinition.prototype.getRelation = function(entityName, relationName) {
        var relation, _i, _len, _ref;
        _ref = this.getEntity(entityName).relations;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          relation = _ref[_i];
          if (relation.name === relationName) {
            return relation;
          }
        }
      };
  
      return SchemaDefinition;
  
    })();
  
    module.exports = SchemaDefinition;
  
  }).call(this);
  