Creating New Fields

    Columns in database tables are handled via the DFField interface. Each field belongs to its parent entity, which is DIF's abstraction of a database table. A field has a defined data type (eg integer, text, image, date), allowing the DIF to handle column data in appropriate ways. In this example the field is a single database column, but the DFField abstraction allows data to be obtained from multiple sources so richer data types are available. Data types are handled by the interface DFCapability and define the required class when creating the new field. A full list of DFField types is available on the DFCapability page.

    There are numerous helper methods for creating fields in DFFields class. This scriptlet creates a text field called 'Annotation' using one of the helper methods, reducing the command to a single line. As you are editing the table you will need to create a locked environment.

    import com.im.commons.progress.*
    import com.im.df.api.ddl.*
    
    def entity = dataTree.rootVertex.entity
    def schema = dataTree.schema
    
    schema.lockable.withLock('create the new field'){ envRW ->
        def textField = DFFields.createTextField(entity, 'Annotation', 'Annotation', 1024, envRW)
    }

    In most cases the native type for a text field is VARCHAR2, which is also the type that is used in DFFields.createTextField() method above. If you need to create a BLOB field, you may to change the native type. It's a little bit more work, because there is no helper method for creating BLOB text fields directly. You can check the native type and switch if necessary using the scriptlet below.

    import com.im.commons.progress.*
    import com.im.df.api.capabilities.*
    import com.im.df.api.util.*
    import com.im.commons.db.ddl.DBDatabaseInfo.ColumnSQLType
    
    def schema = dataTree.schema
    def ety = dataTree.rootVertex.entity
    
    schema.lockable.withLock('create the new field'){ envRW ->
        def Class[] req1 = [ DBFieldCapability.class, DFFieldTextCapability.class ]
        def nt = DIFUtilities.findFirstAppropriateNewType(ety.getFields().getNewTypes(), false, req1, new Class[0])
        nt.options.newDFItemNameSafe = "ssColName"
        def col = nt.options.columns[0]
        def nativeTypeBlob = null
    
        // search for BLOB native type
        for (def nativeType : col.allNativeTypeDefinitions) {
            if (nativeType.columnType == ColumnSQLType.BLOB) {
                nativeTypeBlob = nativeType;
            }
        }
        if (nativeTypeBlob != null) {
            // resize default BLOB native type and assign it to column type definition
            col.nativeTypeDefinition = nativeTypeBlob.reSize(20000);
        }
        nt.create(envRW)
    }

    The following example shows a way how to create a binary field. The script creates a new entity and puts a new binary field into it. Therefore, it must run from the Schema and not the Data Tree.

    import com.im.commons.progress.*
    import com.im.df.api.capabilities.*
    import com.im.df.api.util.*;
    import com.im.df.api.ddl.*;
    
    schema.lockable.withLock('create new jchem entity') { env ->
        def newEntity = DFEntities.createJChemEntity(schema, 'New JChem Entity', env)
    
        def Class[] req = [ DFFieldBinaryCapability ]
        def nt = DIFUtilities.findFirstAppropriateNewType(newEntity.getFields().getNewTypes(), false, req, new Class[0]);
        nt.options.newDFItemNameSafe = 'New Binary Field'
        println "New type valid and ready for creating binary field:" + nt.options.valid
        def newBinField = nt.create(env).iterator().next()
    }