removed "field-procs", improved csv -handling

This commit is contained in:
Ralf Wisser
2020-09-11 18:29:35 +02:00
parent 578f78f175
commit 423d36459f
14 changed files with 194 additions and 87 deletions
+7
View File
@@ -1,3 +1,10 @@
9.5.5
- Fix for "Need help understanding delete script"
(A further release was necessary, as this was not completely corrected at first)
- Fix for "Delete Reduction is not deleting rows"
https://sourceforge.net/p/jailer/discussion/700499/thread/3d16e17980/
- removed "field-procs", improved csv -handling
9.5.4
- Deactivated dependencies had no effect on topological sorting. This was corrected.
https://sourceforge.net/p/jailer/discussion/700499/thread/b3685a49
@@ -25,7 +25,7 @@ public class JailerVersion {
/**
* The Jailer version.
*/
public static final String VERSION = "9.5.4.4";
public static final String VERSION = "9.5.4.8";
/**
* The Jailer working tables version.
@@ -22,6 +22,8 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sf.jailer.restrictionmodel.RestrictionModel;
import net.sf.jailer.util.Pair;
@@ -593,6 +595,17 @@ public class Association extends ModelElement {
}
}
private static final String NULL_FILTER_COMMENT_PREFIX = "disabled dependency: ";
private static final Pattern NULL_FILTER_PATTERN = Pattern.compile("(?i:\\s*(/\\*.*\\*/\\s*)?null(\\s*/\\*.*\\*/)?)\\s*");
private boolean isNullFilter(Filter filter) {
return filter.getExpression() != null
&&
(NULL_FILTER_PATTERN.matcher(filter.getExpression()).matches()
||
Filter.EXCLUDED_VALUE.equals(filter.getExpression()));
}
public boolean hasNullableFK() {
if (!isInsertDestinationBeforeSource()) {
return false;
@@ -605,7 +618,7 @@ public class Association extends ModelElement {
if (!c.isNullable) {
return false;
}
if (c.getFilter() != null && !c.getFilter().isDerived() && !c.getFilter().isNullFilter()) {
if (c.getFilter() != null && !c.getFilter().isDerived() && !isNullFilter(c.getFilter())) {
return false;
}
for (Column pk: source.primaryKey.getColumns()) {
@@ -620,7 +633,17 @@ public class Association extends ModelElement {
public boolean fkHasNullFilter() {
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
for (Column c: sdMap.keySet()) {
if (c.getFilter() == null || !c.getFilter().isNullFilter()) {
if (c.getFilter() == null || !isNullFilter(c.getFilter())) {
return false;
}
}
return true;
}
public boolean fkHasExcludeFilter() {
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
for (Column c: sdMap.keySet()) {
if (c.getFilter() == null || !Filter.EXCLUDED_VALUE.equals(c.getFilter().getExpression())) {
return false;
}
}
@@ -632,15 +655,15 @@ public class Association extends ModelElement {
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
for (Column c: sdMap.keySet()) {
if (set) {
if (c.getFilter() == null || !"null".equals(c.getFilter().getExpression())) {
if (c.getFilter() == null || !isNullFilter(c.getFilter())) {
c.setFilter(new Filter("null /* " + NULL_FILTER_COMMENT_PREFIX + getName() + " */", null, false, null));
changed = true;
}
c.setFilter(new Filter("null", null, false, null));
} else {
if (c.getFilter() != null) {
c.setFilter(null);
changed = true;
}
c.setFilter(null);
}
}
getDataModel().deriveFilters();
@@ -184,8 +184,4 @@ public class Filter {
return applyAtExport;
}
public boolean isNullFilter() {
return "null".equalsIgnoreCase(expression.trim());
}
}
@@ -257,18 +257,6 @@ public class LocalEntityGraph extends EntityGraph {
this.localInlineViewStyle = InlineViewStyle.forSession(localSession);
this.remoteInlineViewStyle = InlineViewStyle.forSession(remoteSession);
new DDLCreator(executionContext).createDDL(getDatamodel(), localSession, WorkingTableScope.GLOBAL, rowIdSupport, null);
File fieldProcTablesFile = new File("field-proc-tables.csv");
if (fieldProcTablesFile.exists()) {
try {
for (CsvFile.Line line: new CsvFile(fieldProcTablesFile).getLines()) {
fieldProcTables.add(line.cells.get(0).toLowerCase(Locale.ENGLISH));
}
Session._log.info("tables with field procedures: " + fieldProcTables);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
/**
@@ -1166,9 +1154,11 @@ public class LocalEntityGraph extends EntityGraph {
*/
@Override
public long removeAssociatedDestinations(final Association association, final boolean deletedEntitiesAreMarked, Set<Table> allTables) throws SQLException {
final String jc = association.getJoinCondition();
String jc = association.getJoinCondition();
checkPseudoColumns(association.source, jc);
if (jc != null) {
jc = SqlUtil.resolvePseudoColumns(association.getJoinCondition(), 0, birthdayOfSubject, association.reversed, inDeleteMode);
final String destAlias;
final String sourceAlias;
if (association.reversed) {
@@ -1189,7 +1179,9 @@ public class LocalEntityGraph extends EntityGraph {
"Select " + upkColumnList(association.destination, "EB", "") + " from " + dmlTableReference(ENTITY, localSession) + " EB " +
"Where " + (deletedEntitiesAreMarked? "EB.birthday>=0 and " : "") +
"EB.r_entitygraph=" + graphID + " and EB.type=" + typeName(association.destination) + " ";
final String finalJc = jc;
localSession.executeQuery(selectEB, new RemoteInlineViewBuilder("EB", upkColumnList(association.destination, ""), true) {
@Override
@@ -1198,7 +1190,7 @@ public class LocalEntityGraph extends EntityGraph {
String selectSource =
"Select distinct " + upkColumnList(association.destination, "EB", "") + (checkDest? sep + pkList(association.source, sourceAlias, "") : "") + " from " + inlineView + " " +
"join " + quoting.requote(association.destination.getName()) + " " + destAlias + " on "+ pkEqualsEntityID(association.destination, destAlias, "EB", "", false) + " " +
"join " + quoting.requote(association.source.getName()) + " " + sourceAlias + " " + " on " + jc;
"join " + quoting.requote(association.source.getName()) + " " + sourceAlias + " " + " on " + finalJc;
remoteSession.executeQuery(selectSource, new LocalInlineViewBuilder("EBA", upkColumnList(association.destination, null, "EB") + (checkDest? sep + upkColumnList(association.source, "A") : ""), true) {
@@ -95,20 +95,8 @@ public class RemoteEntityGraph extends EntityGraph {
this.universalPrimaryKey = universalPrimaryKey;
this.updateStatistics = updateStatistics;
this.rowIdSupport = new RowIdSupport(dataModel, session.dbms, executionContext);
File fieldProcTablesFile = new File("field-proc-tables.csv");
if (fieldProcTablesFile.exists()) {
try {
for (CsvFile.Line line: new CsvFile(fieldProcTablesFile).getLines()) {
fieldProcTables.add(line.cells.get(0).toLowerCase(Locale.ENGLISH));
}
Session._log.info("tables with field procedures: " + fieldProcTables);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
private final Quoting quoting;
/**
@@ -183,7 +183,12 @@ public class ExtractionModel {
* The restricted data-model to be used for extraction.
*/
public final DataModel dataModel;
/**
* Version.
*/
public final int[] version;
/**
* Constructor for empty restriction models.
*
@@ -191,6 +196,7 @@ public class ExtractionModel {
*/
public ExtractionModel(DataModel dataModel, ExecutionContext executionContext) {
this.dataModel = dataModel;
this.version = null;
subject = dataModel.getTables().iterator().hasNext()? dataModel.getTables().iterator().next() : null;
condition = "";
dataModel.setRestrictionModel(new RestrictionModel(dataModel, executionContext));
@@ -215,7 +221,8 @@ public class ExtractionModel {
*/
public ExtractionModel(URL modelURL, Map<String, String> sourceSchemaMapping, Map<String, String> parameters, ExecutionContext executionContext, boolean failOnMissingSubject) throws IOException {
String csvLocation = modelURL.toString();
List<CsvFile.Line> csv = new CsvFile(modelURL.openStream(), null, csvLocation, null).getLines();
CsvFile csvFile = new CsvFile(modelURL.openStream(), CsvFile.ALL_BLOCKS, csvLocation, null);
List<CsvFile.Line> csv = csvFile.getLines();
if (csv.isEmpty()) {
throw new RuntimeException(modelURL + "' is empty");
}
@@ -241,7 +248,7 @@ public class ExtractionModel {
dataModel.setRestrictionModel(new RestrictionModel(dataModel, executionContext));
}
try {
dataModel.getRestrictionModel().addRestrictionDefinition(modelURL, parameters);
dataModel.getRestrictionModel().addRestrictionDefinition(csvFile, csvLocation, parameters);
} catch (Exception e) {
throw new RuntimeException(location, e);
}
@@ -250,7 +257,7 @@ public class ExtractionModel {
this.dataModel = dataModel;
// read xml mapping
List<CsvFile.Line> xmlMapping = new CsvFile(modelURL.openStream(), "xml-mapping", csvLocation, null).getLines();
List<CsvFile.Line> xmlMapping = csvFile.getLines("xml-mapping");
for (CsvFile.Line xmLine: xmlMapping) {
location = subjectLine.location;
String name = xmLine.cells.get(0);
@@ -268,7 +275,7 @@ public class ExtractionModel {
}
// read upserts
List<CsvFile.Line> upserts = new CsvFile(modelURL.openStream(), "upserts", csvLocation, null).getLines();
List<CsvFile.Line> upserts = csvFile.getLines("upserts");
for (CsvFile.Line upsert: upserts) {
location = subjectLine.location;
String name = upsert.cells.get(0);
@@ -282,7 +289,7 @@ public class ExtractionModel {
}
// read "exclude from deletion"
List<CsvFile.Line> excludes = new CsvFile(modelURL.openStream(), "exclude from deletion", csvLocation, null).getLines();
List<CsvFile.Line> excludes = csvFile.getLines("exclude from deletion");
for (CsvFile.Line excludesLine: excludes) {
location = subjectLine.location;
String name = excludesLine.cells.get(0);
@@ -296,14 +303,14 @@ public class ExtractionModel {
}
// read export modus
List<CsvFile.Line> exportModusFile = new CsvFile(modelURL.openStream(), "export modus", csvLocation, null).getLines();
List<CsvFile.Line> exportModusFile = csvFile.getLines("export modus");
Iterator<CsvFile.Line> i = exportModusFile.iterator();
if (i.hasNext()) {
dataModel.setExportModus(i.next().cells.get(0));
}
// read column mapping
List<CsvFile.Line> columnMappingFile = new CsvFile(modelURL.openStream(), "xml column mapping", csvLocation, null).getLines();
List<CsvFile.Line> columnMappingFile = csvFile.getLines("xml column mapping");
for (CsvFile.Line xmLine: columnMappingFile) {
String name = xmLine.cells.get(0);
String mapping = xmLine.cells.get(1);
@@ -316,7 +323,7 @@ public class ExtractionModel {
}
// read filters
List<CsvFile.Line> filtersFile = new CsvFile(modelURL.openStream(), "filters", csvLocation, null).getLines();
List<CsvFile.Line> filtersFile = csvFile.getLines("filters");
for (CsvFile.Line xmLine: filtersFile) {
String name = xmLine.cells.get(0);
String column = xmLine.cells.get(1);
@@ -348,7 +355,7 @@ public class ExtractionModel {
}
// read filter templates
List<CsvFile.Line> templatesFile = new CsvFile(modelURL.openStream(), "filter templates", csvLocation, null).getLines();
List<CsvFile.Line> templatesFile = csvFile.getLines("filter templates");
int lineNr = 0;
FilterTemplate template = null;
while (lineNr < templatesFile.size()) {
@@ -376,7 +383,7 @@ public class ExtractionModel {
}
// read xml settings
List<CsvFile.Line> xmlSettingsFile = new CsvFile(modelURL.openStream(), "xml settings", csvLocation, null).getLines();
List<CsvFile.Line> xmlSettingsFile = csvFile.getLines("xml settings");
i = xmlSettingsFile.iterator();
if (i.hasNext()) {
List<String> cells = i.next().cells;
@@ -386,28 +393,30 @@ public class ExtractionModel {
}
// read version
int[] version = null;
List<CsvFile.Line> versionBlock = new CsvFile(modelURL.openStream(), "version", csvLocation, null).getLines();
List<CsvFile.Line> versionBlock = csvFile.getLines("version");
if (!versionBlock.isEmpty()) {
String vCell = versionBlock.get(0).cells.get(0);
String[] versionLine = vCell.split("[^0-9]+");
version = new int[Math.max(4, versionLine.length)];
int[] v = new int[Math.max(4, versionLine.length)];
int p = 0;
for (String number: versionLine) {
if (number.length() > 0) {
try {
version[p++] = Integer.parseInt(number);
v[p++] = Integer.parseInt(number);
} catch (NumberFormatException e) {
// version is unknown
version = null;
v = null;
break;
}
}
}
version = v;
} else {
version = null;
}
// read additional subjects
List<CsvFile.Line> additionalSubsLines = new CsvFile(modelURL.openStream(), "additional subjects", csvLocation, null).getLines();
List<CsvFile.Line> additionalSubsLines = csvFile.getLines("additional subjects");
for (CsvFile.Line line: additionalSubsLines) {
Table additSubject = getTable(dataModel, SqlUtil.mappedSchema(sourceSchemaMapping, line.cells.get(0)));
if (additSubject != null) {
@@ -416,7 +425,41 @@ public class ExtractionModel {
}
dataModel.deriveFilters();
disableUnknownAssociations(new CsvFile(modelURL.openStream(), "known", csvLocation, null).getLines());
disableUnknownAssociations(csvFile.getLines("known"));
if (version != null) {
int v1 = version.length > 0? version[0] : 0;
int v2 = version.length > 1? version[1] : 0;
int v3 = version.length > 2? version[2] : 0;
int v4 = version.length > 3? version[3] : 0;
// < 9.5.4.6
if (v1 < 9 || (v1 == 9 && (v2 < 5 || (v2 == 5 && (v3 < 4 || (v3 == 4 && (v4 < 6))))))) {
migrateDisabledFKNullFilter();
}
}
}
private void migrateDisabledFKNullFilter() {
for (Table table: dataModel.getTables()) {
for (Association association: table.associations) {
if (association.isInsertDestinationBeforeSource() && association.isIgnored()) {
Map<Column, Column> sdMap = association.createSourceToDestinationKeyMapping();
boolean hasNullFilter = true;
for (Column c: sdMap.keySet()) {
if (c.getFilter() == null || !"null".equals(c.getFilter().getExpression())) {
hasNullFilter = false;
break;
}
}
if (hasNullFilter) {
for (Column c: sdMap.keySet()) {
c.setFilter(null);
}
association.setOrResetFKNullFilter(true);
}
}
}
}
}
private SubjectLimitDefinition createLimitDefinition(String limit, String orderBy) {
@@ -115,17 +115,27 @@ public class RestrictionModel {
}
return rest;
}
/**
* Adds restrictions defined in a restriction-file.
*
* @param parameters apply this parameter-value mapping to all restriction conditions
*/
public void addRestrictionDefinition(URL extractionModelURL, Map<String, String> parameters) throws Exception {
addRestrictionDefinition(new CsvFile(extractionModelURL.openStream(), null, extractionModelURL.toString(), null), extractionModelURL.toString(), parameters);
}
/**
* Adds restrictions defined in a restriction-file.
*
* @param parameters apply this parameter-value mapping to all restriction conditions
* @param fileName
*/
public void addRestrictionDefinition(CsvFile csvFile, String fileName, Map<String, String> parameters) throws Exception {
if (dataModel != null) {
dataModel.version++;
}
List<CsvFile.Line> lines = new CsvFile(extractionModelURL.openStream(), null, extractionModelURL.toString(), null).getLines();
List<CsvFile.Line> lines = csvFile.getLines();
int nr = 0;
for (CsvFile.Line line: lines) {
++nr;
@@ -218,7 +228,7 @@ public class RestrictionModel {
}
}
}
filesRead.add(extractionModelURL.toString());
filesRead.add(fileName);
}
/**
+57 -18
View File
@@ -22,7 +22,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Parser for CSV-files.
@@ -59,7 +61,7 @@ public class CsvFile {
*/
public Line(String location, List<String> cells) {
this.location = location;
this.cells = new ArrayList<String>(cells);
this.cells = cells;
int num = 0;
int l = 0;
for (String s : cells) {
@@ -68,8 +70,8 @@ public class CsvFile {
l = num;
}
}
for (int i = 0; i < 10; ++i) {
this.cells.add("");
for (int i = 0; i < 32; ++i) {
this.cells.add(""); // legacy
}
this.length = l;
}
@@ -171,15 +173,12 @@ public class CsvFile {
if (!inBlock) {
continue;
}
List<String> row = new ArrayList<String>();
String[] col = decodeLine(line);
List<String> row = new ArrayList<String>(col.length + 34);
for (int i = 0; i < col.length; ++i) {
String s = col[i];
row.add(s.trim());
}
while (row.size() < 100) {
row.add("");
}
Line cvsLine = new Line(csvFile.getName() + ", line " + lineNr, row);
if (filter == null || filter.accept(cvsLine)) {
rows.add(cvsLine);
@@ -188,7 +187,17 @@ public class CsvFile {
reader.close();
}
}
/**
* Special block-name for reading default block and cache all others.
*
* @see CsvFile#getLines()
*/
public static final String ALL_BLOCKS = "all-blocks";
private static final String DEFAULT_BLOCK = "default-block";
private Map<String, List<Line>> blocks = null;
/**
* Constructor.
*
@@ -200,40 +209,52 @@ public class CsvFile {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
int lineNr = 0;
boolean all = ALL_BLOCKS.equals(block);
if (all) {
block = null;
blocks = new HashMap<String, List<Line>>();
}
boolean inBlock = block == null;
String blockName = null;
while ((line = reader.readLine()) != null) {
++lineNr;
if (line.trim().length() == 0) {
continue;
}
if (line.trim().startsWith(BLOCK_INDICATOR)) {
if (inBlock) {
break;
if (all) {
blocks.put(blockName == null? DEFAULT_BLOCK : blockName, rows);
rows = new ArrayList<CsvFile.Line>();
} else {
if (inBlock) {
break;
}
}
String blockName = line.trim().substring(BLOCK_INDICATOR.length()).trim();
inBlock = block.equals(blockName);
blockName = line.trim().substring(BLOCK_INDICATOR.length()).trim();
inBlock = blockName.equals(block);
continue;
}
if (line.trim().startsWith("#")) {
continue;
}
if (!inBlock) {
if (!inBlock && !all) {
continue;
}
List<String> row = new ArrayList<String>();
String[] col = decodeLine(line);
List<String> row = new ArrayList<String>(col.length + 34);
for (int i = 0; i < col.length; ++i) {
String s = col[i];
row.add(s.trim());
}
while (row.size() < 100) {
row.add("");
}
Line cvsLine = new Line(location + ", " + "line " + lineNr, row);
if (filter == null || filter.accept(cvsLine)) {
rows.add(cvsLine);
}
}
if (all) {
blocks.put(blockName == null? DEFAULT_BLOCK : blockName, rows);
rows = new ArrayList<CsvFile.Line>();
}
in.close();
}
}
@@ -307,7 +328,25 @@ public class CsvFile {
* @return list of lists of cell-contents
*/
public List<Line> getLines() {
return rows;
if (blocks != null) {
return getLines(null);
} else {
return rows;
}
}
/**
* Gets the list of lines of a cached block.
*
* @return list of lists of cell-contents of given block
*
* @see CsvFile#ALL_BLOCKS
*/
public List<Line> getLines(String block) {
if (blocks == null) {
throw new IllegalStateException();
}
return blocks.get(block == null? DEFAULT_BLOCK : block);
}
/**
@@ -318,7 +318,7 @@ public class DataModelEditor extends javax.swing.JDialog {
if (merge && modelFinderColumnFile.exists()) {
for (CsvFile.Line l: new CsvFile(modelFinderColumnFile).getLines()) {
CsvFile.Line ol = columns.get(l.cells.get(0));
if (ol == null || !ol.cells.equals(l.cells)) {
if (ol == null || !ol.toString().equals(l.toString())) {
modifiedColumnTables.add(l.cells.get(0));
markDirty();
}
@@ -2085,12 +2085,13 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
private void initRestrictedDependencyWarningField() {
boolean restrictedDep = currentAssociation != null && !ScriptFormat.XML.equals(scriptFormat) && currentAssociation.isInsertDestinationBeforeSource() && currentAssociation.isRestricted();
restrictionEditor.restrictedDependencyWarning.setVisible(restrictedDep);
// TODO Differentiated filtering of restricted dependencies
restrictionEditor.fkToNullCheckBox.setVisible(restrictedDep && (RestrictionModel.IGNORE.equals(currentAssociation.getRestrictionCondition()) || "false".equals(currentAssociation.getRestrictionCondition()))); // TODO
restrictionEditor.fkToNullCheckBox.setEnabled(restrictedDep && currentAssociation.hasNullableFK());
restrictionEditor.fkToNullCheckBox.setEnabled(restrictedDep && currentAssociation.hasNullableFK() && !currentAssociation.fkHasExcludeFilter());
restrictionEditor.fkToNullCheckBox.setSelected(restrictedDep && currentAssociation.fkHasNullFilter());
restrictionEditor.restrictedDependencyWarning.setVisible(restrictedDep && !currentAssociation.fkHasNullFilter());
restrictionEditor.updateHint();
}
/**
@@ -3471,6 +3472,4 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
private static final long serialVersionUID = -5640822484296649670L;
// TODO make "nullFks-filters" distictable from others. Migrate such filters. Avoid loading restriction-model-files more than once.
}
@@ -216,7 +216,7 @@
<SubComponents>
<Component class="javax.swing.JCheckBox" name="fkToNullCheckBox">
<Properties>
<Property name="text" type="java.lang.String" value="Set dangling foreign key columns to null "/>
<Property name="text" type="java.lang.String" value="Set foreign key columns to null "/>
<Property name="toolTipText" type="java.lang.String" value="&lt;html&gt;&lt;i&gt;on Export&lt;/i&gt;: Set all foreign keys to null to which the row with the corresponding primary key is not exported. &lt;br&gt;&lt;hr&gt;&#xa;&lt;i&gt;on Delete&lt;/i&gt;: Set all foreign keys in the rows that cannot be deleted to null when the row with the corresponding primary key is deleted.&lt;/html&gt;"/>
</Properties>
<Events>
@@ -249,6 +249,9 @@
</Property>
<Property name="text" type="java.lang.String" value="(Foreign key is not nullable)"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="1"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
@@ -230,7 +230,7 @@ public class RestrictionEditor extends javax.swing.JPanel {
jPanel10.setOpaque(false);
jPanel10.setLayout(new java.awt.GridBagLayout());
fkToNullCheckBox.setText("Set dangling foreign key columns to null ");
fkToNullCheckBox.setText("Set foreign key columns to null ");
fkToNullCheckBox.setToolTipText("<html><i>on Export</i>: Set all foreign keys to null to which the row with the corresponding primary key is not exported. <br><hr>\n<i>on Delete</i>: Set all foreign keys in the rows that cannot be deleted to null when the row with the corresponding primary key is deleted.</html>");
fkToNullCheckBox.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentShown(java.awt.event.ComponentEvent evt) {
@@ -358,10 +358,14 @@ public class RestrictionEditor extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents
private void fkToNullCheckBoxPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_fkToNullCheckBoxPropertyChange
fk20DisabledHintLabel.setVisible(fkToNullCheckBox.isVisible() && !fkToNullCheckBox.isEnabled());
fk20DisabledHintLabel.setToolTipText(fkToNullCheckBox.getToolTipText());
updateHint();
}//GEN-LAST:event_fkToNullCheckBoxPropertyChange
public void updateHint() {
fk20DisabledHintLabel.setVisible(fkToNullCheckBox.isVisible() && !fkToNullCheckBox.isEnabled() && !fkToNullCheckBox.isSelected());
fk20DisabledHintLabel.setToolTipText(fkToNullCheckBox.getToolTipText());
}
private void fkToNullCheckBoxComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_fkToNullCheckBoxComponentShown
fkToNullCheckBoxPropertyChange(null);
}//GEN-LAST:event_fkToNullCheckBoxComponentShown
@@ -376,7 +380,7 @@ public class RestrictionEditor extends javax.swing.JPanel {
javax.swing.JLabel columnsA;
javax.swing.JLabel columnsB;
public javax.swing.JLabel destination;
private javax.swing.JLabel fk20DisabledHintLabel;
public javax.swing.JLabel fk20DisabledHintLabel;
public javax.swing.JCheckBox fkToNullCheckBox;
public javax.swing.JRadioButton ignore;
private javax.swing.JLabel jLabel1;
@@ -945,6 +945,9 @@ public abstract class TableEditor extends javax.swing.JDialog {
// update author
for (int i = 0; i < tableLine.cells.size() ; ++i) {
if ("".equals(tableLine.cells.get(i))) {
while (tableLine.cells.size() <= i) {
tableLine.cells.add("");
}
tableLine.cells.set(i+1, DataModelEditor.DATA_MODEL_EDITOR_AUTHOR);
break;
}