OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 93 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 93 Rev 142
Line 15... Line 15...
15
 * Field created on 4 mai 2004
15
 * Field created on 4 mai 2004
16
 */
16
 */
17
package org.openconcerto.sql.model;
17
package org.openconcerto.sql.model;
18
 
18
 
19
import static org.openconcerto.sql.model.SQLBase.quoteIdentifier;
19
import static org.openconcerto.sql.model.SQLBase.quoteIdentifier;
-
 
20
 
20
import org.openconcerto.sql.Log;
21
import org.openconcerto.sql.Log;
-
 
22
import org.openconcerto.sql.model.SQLTable.FieldGroup;
21
import org.openconcerto.sql.model.graph.Link;
23
import org.openconcerto.sql.model.graph.Link;
22
import org.openconcerto.sql.model.graph.Path;
24
import org.openconcerto.sql.model.graph.Path;
-
 
25
import org.openconcerto.sql.model.graph.SQLKey.Type;
23
import org.openconcerto.utils.CollectionUtils;
26
import org.openconcerto.utils.CollectionUtils;
24
import org.openconcerto.utils.CompareUtils;
27
import org.openconcerto.utils.CompareUtils;
25
import org.openconcerto.utils.ExceptionUtils;
28
import org.openconcerto.utils.ExceptionUtils;
26
import org.openconcerto.utils.Value;
29
import org.openconcerto.utils.Value;
27
import org.openconcerto.xml.JDOMUtils;
30
import org.openconcerto.xml.JDOM2Utils;
28
import org.openconcerto.xml.XMLCodecUtils;
31
import org.openconcerto.xml.XMLCodecUtils;
29
 
32
 
30
import java.math.BigDecimal;
33
import java.math.BigDecimal;
31
import java.sql.DatabaseMetaData;
34
import java.sql.DatabaseMetaData;
32
import java.sql.ResultSet;
35
import java.sql.ResultSet;
Line 41... Line 44...
41
import java.util.Map.Entry;
44
import java.util.Map.Entry;
42
import java.util.logging.Level;
45
import java.util.logging.Level;
43
import java.util.regex.Matcher;
46
import java.util.regex.Matcher;
44
import java.util.regex.Pattern;
47
import java.util.regex.Pattern;
45
 
48
 
-
 
49
import org.jdom2.Element;
-
 
50
 
46
import net.jcip.annotations.GuardedBy;
51
import net.jcip.annotations.GuardedBy;
47
import net.jcip.annotations.ThreadSafe;
52
import net.jcip.annotations.ThreadSafe;
48
 
53
 
49
import org.jdom2.Element;
-
 
50
 
-
 
51
/**
54
/**
52
 * Un champ SQL. Pour obtenir une instance de cette classe il faut utiliser
55
 * Un champ SQL. Pour obtenir une instance de cette classe il faut utiliser
53
 * {@link SQLTable#getField(String)}. Un champ connait sa table, son nom, son type et sa valeur par
56
 * {@link SQLTable#getField(String)}. Un champ connait sa table, son nom, son type et sa valeur par
54
 * défaut.
57
 * défaut.
55
 * 
58
 * 
Line 239... Line 242...
239
     * 
242
     * 
240
     * @return the SQL for the type, e.g. "int" or "decimal(16,8)".
243
     * @return the SQL for the type, e.g. "int" or "decimal(16,8)".
241
     * @see SQLSyntax#getType(SQLField)
244
     * @see SQLSyntax#getType(SQLField)
242
     */
245
     */
243
    public final String getTypeDecl() {
246
    public final String getTypeDecl() {
244
        return this.getServer().getSQLSystem().getSyntax().getType(this);
247
        return this.getDBSystemRoot().getSyntax().getType(this);
245
    }
248
    }
246
 
249
 
247
    /**
250
    /**
248
     * Metadata from JDBC.
251
     * Metadata from JDBC.
249
     * 
252
     * 
Line 366... Line 369...
366
    public synchronized final Boolean isNullable() {
369
    public synchronized final Boolean isNullable() {
367
        return this.nullable;
370
        return this.nullable;
368
    }
371
    }
369
 
372
 
370
    public boolean isKey() {
373
    public boolean isKey() {
371
        return this.getTable().getKeys().contains(this);
374
        return this.isPrimaryKey() || this.isForeignKey();
372
    }
375
    }
373
 
376
 
374
    /**
377
    /**
375
     * Is this the one and only field in the primary key of its table.
378
     * Is this the one and only field in the primary key of its table.
376
     * 
379
     * 
Line 379... Line 382...
379
     */
382
     */
380
    public boolean isPrimaryKey() {
383
    public boolean isPrimaryKey() {
381
        return this.getTable().getPrimaryKeys().equals(Collections.singleton(this));
384
        return this.getTable().getPrimaryKeys().equals(Collections.singleton(this));
382
    }
385
    }
383
 
386
 
-
 
387
    /**
-
 
388
     * Is this the one and only field in a foreign key of its table.
-
 
389
     * 
-
 
390
     * @return <code>true</code> if this is part of a foreign key that has no other fields.
-
 
391
     * @see #getFieldGroup()
-
 
392
     */
-
 
393
    public boolean isForeignKey() {
-
 
394
        final FieldGroup fieldGroup = getFieldGroup();
-
 
395
        return fieldGroup.getKeyType() == Type.FOREIGN_KEY && fieldGroup.getSingleField() != null;
-
 
396
    }
-
 
397
 
-
 
398
    /**
-
 
399
     * To which group this field belong.
-
 
400
     * 
-
 
401
     * @return the group of this field.
-
 
402
     * @see SQLTable#getFieldGroups()
-
 
403
     */
-
 
404
    public FieldGroup getFieldGroup() {
-
 
405
        return this.getTable().getFieldGroups().get(this.getName());
-
 
406
    }
-
 
407
 
384
    public final SQLTable getForeignTable() {
408
    public final SQLTable getForeignTable() {
385
        return this.getDBSystemRoot().getGraph().getForeignTable(this);
409
        return this.getDBSystemRoot().getGraph().getForeignTable(this);
386
    }
410
    }
387
 
411
 
388
    public final Link getLink() {
412
    public final Link getLink() {
Line 425... Line 449...
425
 
449
 
426
    public synchronized String toXML() {
450
    public synchronized String toXML() {
427
        if (this.xml == null) {
451
        if (this.xml == null) {
428
            final StringBuilder sb = new StringBuilder(2048);
452
            final StringBuilder sb = new StringBuilder(2048);
429
            sb.append("<field name=\"");
453
            sb.append("<field name=\"");
430
            sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(this.getName()));
454
            sb.append(JDOM2Utils.OUTPUTTER.escapeAttributeEntities(this.getName()));
431
            sb.append("\" >");
455
            sb.append("\" >");
432
            sb.append(this.type.toXML());
456
            sb.append(this.type.toXML());
433
            sb.append(XMLCodecUtils.encodeSimple(this.metadata));
457
            sb.append(XMLCodecUtils.encodeSimple(this.metadata));
434
            sb.append("<infoSchema>");
458
            sb.append("<infoSchema>");
435
            sb.append(XMLCodecUtils.encodeSimple(this.infoSchemaCols));
459
            sb.append(XMLCodecUtils.encodeSimple(this.infoSchemaCols));
Line 466... Line 490...
466
     * @param otherSystem the system <code>o</code> originated from, can be <code>null</code>.
490
     * @param otherSystem the system <code>o</code> originated from, can be <code>null</code>.
467
     * @param compareDefault <code>true</code> if defaults should be compared.
491
     * @param compareDefault <code>true</code> if defaults should be compared.
468
     * @return a map containing properties that differs and their values.
492
     * @return a map containing properties that differs and their values.
469
     */
493
     */
470
    public synchronized Map<Properties, String> getDiffMap(SQLField o, SQLSystem otherSystem, boolean compareDefault) {
494
    public synchronized Map<Properties, String> getDiffMap(SQLField o, SQLSystem otherSystem, boolean compareDefault) {
471
        final Map<Properties, String> res = new HashMap<Properties, String>();
-
 
472
        if (o == null)
495
        if (o == null)
473
            res.put(null, "other field is null");
496
            return Collections.singletonMap(null, "other field is null");
-
 
497
        final Map<Properties, String> res = new HashMap<Properties, String>();
474
        if (!this.getName().equals(o.getName()))
498
        if (!this.getName().equals(o.getName()))
475
            res.put(Properties.NAME, "name unequal : " + quoteIdentifier(this.getName()) + " != " + quoteIdentifier(o.getName()));
499
            res.put(Properties.NAME, "name unequal : " + quoteIdentifier(this.getName()) + " != " + quoteIdentifier(o.getName()));
476
        if (!this.getType().equals(o.getType(), otherSystem))
500
        if (!this.getType().equals(o.getType(), otherSystem))
477
            res.put(Properties.TYPE, "type unequal : " + this.getType() + " " + o.getType());
501
            res.put(Properties.TYPE, "type unequal : " + this.getType() + " " + o.getType());
478
        if (!CompareUtils.equals(this.isNullable(), o.isNullable()))
502
        if (!CompareUtils.equals(this.isNullable(), o.isNullable()))
Line 481... Line 505...
481
            res.put(Properties.DEFAULT, "default unequal : " + print(this.getDefaultValue()) + " != " + print(o.getDefaultValue()));
505
            res.put(Properties.DEFAULT, "default unequal : " + print(this.getDefaultValue()) + " != " + print(o.getDefaultValue()));
482
        return res;
506
        return res;
483
    }
507
    }
484
 
508
 
485
    private boolean defaultEquals(SQLField o) {
509
    private boolean defaultEquals(SQLField o) {
486
        final SQLSyntax syntax = this.getServer().getSQLSystem().getSyntax();
510
        final SQLSyntax syntax = this.getDBSystemRoot().getSyntax();
487
        final SQLSyntax oSyntax = o.getServer().getSQLSystem().getSyntax();
511
        final SQLSyntax oSyntax = o.getDBSystemRoot().getSyntax();
488
        // don't compare actual default for auto fields, e.g. on MySQL it's null on PG it
512
        // don't compare actual default for auto fields, e.g. on MySQL it's null on PG it
489
        // nextval(seq)
513
        // nextval(seq)
490
        if (syntax.isAuto(this) && oSyntax.isAuto(o))
514
        if (syntax.isAuto(this) && oSyntax.isAuto(o))
491
            return true;
515
            return true;
492
        // normalize to this syntax before doing a string comparison
516
        // normalize to this syntax before doing a string comparison