logo

class

sql::DbModel

sys::Obj
  sql::DbModel
  1  //
  2  // Copyright (c) 2008, John Sublett
  3  // Licensed under the Academic Free License version 3.0
  4  //
  5  // History:
  6  //   01 Jan 08  John Sublett  Creation
  7  //
  8  
  9  **
 10  ** DbModel is a collection of types and their relationships
 11  ** to be modeled in a relational database.
 12  **
 13  class DbModel
 14  {
 15    **
 16    ** Add a type to the model.
 17    **
 18    Void addType(Type type)
 19    {
 20      types.add(type)
 21    }
 22    
 23    **
 24    ** Commit the model.  This must be called when all types have
 25    ** been added to the model.  A committed model may have types
 26    ** added or removed, but commit must be called again after
 27    ** the modifications are made.
 28    **
 29    Void commit()
 30    {
 31      // create dependency graph
 32      tg := TypeGraph.make
 33      types.each |Type t|
 34      {
 35        tg.addType(t)
 36        
 37        Type[] dependsOn := dependencies(t)
 38        dependsOn.each |Type dependency|
 39        {
 40          if (!types.contains(dependency))
 41            throw SqlErr.make("Missing dependency.  $t depends on "+dependency+".")
 42          tg.addDependency(t, dependency)
 43        }
 44      }
 45      
 46      // sort by dependency, this results in a list of types
 47      // in the order that the tables need to be created
 48      types = tg.sort
 49    }
 50  
 51    **
 52    ** List the types in the model.  The result is a readonly
 53    ** list of types in this model ordered by dependency.
 54    **
 55    Type[] listTypes()
 56    {
 57      return types.ro
 58    }
 59  
 60    **
 61    ** Get the list of Types that the specified
 62    ** dependent type depends on.
 63    **
 64    static Type[] dependencies(Type dependent)
 65    {
 66      depends := Type[,]
 67      dependent.fields.each |Field f|
 68      {
 69        if (f.of != sys::Uri.type) return
 70        targetType := f.facet("refType")
 71        if ((targetType != null) && !depends.contains(targetType))
 72          depends.add(targetType)
 73      }
 74      
 75      return depends
 76    }
 77  
 78  //////////////////////////////////////////////////////////////////////////
 79  // Fields
 80  //////////////////////////////////////////////////////////////////////////
 81  
 82    private Type[] types := Type[,]
 83  }