Insert or Update a Row

    Inserting and updating a row take a very similar approach, issuing a single call to insert or update a DFEntityDataProvider with an array mapping the field to the new value based on the primary key (usually ID). This is not carried out on the entity itself, but on the data provider. During an update, fields that are not updated will be left alone. The scriptlet below identifies fields, builds a sample array, and then inserts the row based on the id.

    The API call for inserting a row into the DFEntityDataProvider is:

    DFUpdateInfo insert(Map<String,Object> values,
                        Map<String,Object> insertOptions,
                        DFEnvironmentRW env)

    The scriptlet below identifies the DFEntityDataProvider for the DFEntity. It also selects all row IDs fro the full result set on the entity. This code only inserts the string 'Some code' and 'Second column' into the table, but it demonstrates how more complex operations could be used to update other information. A full scripts which demonstrate the usage is MicroSpecies Table Populator.

    def ety = dataTree.rootVertex.entity
    def edp = ety.schema.dataProvider.getEntityDataProvider(ety)
    def resultSet = ety.schema.dataProvider.getDefaultResultSet(dataTree, false, DFEnvironmentRO.DEV_NULL)
    def vertexState = resultSet.getVertexState(dataTree.rootVertex)
    
    def fld1 = ety.fields.items.find { it.name == 'Structure' }
    def fld2 = ety.fields.items.find { it.name == 'DB regid' }
    def fld3 = ety.fields.items.find { it.name == 'DB name' }
    
    def lock = edp.lockable.withLock('Inserting'){ envRW ->
        // Define the values for each field
        def vals = [:]
        vals[fld1.id] = 'C1CCCCC1'
        vals[fld2.id] = 'abc'
        vals[fld3.id] = 'xyz'
    
        // To insert the new row
        def updateInfo = edp.insert(vals, null, envRW)
    
        // To update DataTree and its views
        resultSet.lockable.withLock('Inserting'){ rsEnvRW ->
            vertexState.insertId(updateInfo.id, true, rsEnvRW)
        }
    }

    Updating a row is a little more complex. The array of fields to update must be in the form of a DFUpdateDescription. The API call for this is:

    Map<DFUpdateDescription,DFUpdateResult> update(List<DFUpdateDescription> updateDescriptors,
                           DFUndoConfig undoConfig,
                           DFEnvironmentRW env)

    The DFUpdateDescription is constructured from a map of fields:values, just as above. However, this map is then passed into the DFUpdateDescription constructor to provide a format necessary for update. The example below demonstrates the same functionality as above, but in an update fashion, not an insert fashion. Both the insert and update method can be found on the DFEntityDataProvider page. A full scripts which demonstrate this usage are Table Standardizer

    def ety = dataTree.rootVertex.entity
    def edp = ety.schema.dataProvider.getEntityDataProvider(ety)
    
    def fld1 = ety.fields.items.find { it.name == 'Structure' }
    def fld2 = ety.fields.items.find { it.name == 'DB regid' }
    def fld3 = ety.fields.items.find { it.name == 'DB name' }
    
    def lock = edp.lockable.withLock('Updating'){ envRW ->
        // Define the values for each field
        def vals = [:]
        vals[fld1.id] = 'N1C=CC=C1'
        vals[fld2.id] = 'Mickey'
        vals[fld3.id] = 'Mouse'
    
        // Find the id of the row to update -- eg. id of the last row in the root vertex
        def resultSet = ety.schema.dataProvider.getDefaultResultSet(dataTree, false, DFEnvironmentRO.DEV_NULL)
        def vertexState = resultSet.getVertexState(dataTree.rootVertex)
        def id = vertexState.ids[vertexState.ids.size() - 1]
    
        // Create the DFUpdateDescription and update the DFEntityDataProvider
        def ud = DFUpdateDescription.create(ety, id, vals)
        def submitList = Collections.singletonList(ud)
    
        edp.update(submitList, DFUndoConfig.OFF, envRW)
    }