Search in sources :

Example 1 with Grain

use of ru.curs.celesta.score.Grain in project celesta by CourseOrchestra.

the class DbUpdater method updateDb.

/**
 * Performs update of DB structure based on the decomposed object model.
 */
public void updateDb() {
    String sysSchemaName = score.getSysSchemaName();
    try (T context = createContext()) {
        updateSystemSchema(context);
        // Теперь собираем в память информацию о гранулах на основании того,
        // что
        // хранится в таблице grains.
        Map<String, GrainInfo> dbGrains = new HashMap<>();
        while (schemaCursor.nextInSet()) {
            if (!(EXPECTED_STATUSES.contains(schemaCursor.getState()))) {
                throw new CelestaException("Cannot proceed with database upgrade: there are %s " + "not in 'ready', 'recover' or 'lock' state.", getSchemasTableName());
            }
            GrainInfo gi = new GrainInfo();
            gi.checksum = (int) Long.parseLong(schemaCursor.getChecksum(), 16);
            gi.length = schemaCursor.getLength();
            gi.recover = schemaCursor.getState() == ISchemaCursor.RECOVER;
            gi.lock = schemaCursor.getState() == ISchemaCursor.LOCK;
            try {
                gi.version = new VersionString(schemaCursor.getVersion());
            } catch (ParseException e) {
                throw new CelestaException(String.format("Error while scanning %s.%s table: %s", sysSchemaName, getSchemasTableName(), e.getMessage()));
            }
            dbGrains.put(schemaCursor.getId(), gi);
        }
        // Получаем список гранул на основе метамодели и сортируем его по
        // порядку зависимости.
        List<Grain> grains = new ArrayList<>(score.getGrains().values());
        Collections.sort(grains, GRAIN_COMPARATOR);
        // Выполняем итерацию по гранулам.
        boolean success = true;
        for (Grain g : grains) {
            if (!g.isAutoupdate()) {
                continue;
            }
            // Запись о грануле есть?
            GrainInfo gi = dbGrains.get(g.getName());
            if (gi == null) {
                insertGrainRec(g);
                success = updateGrain(g, connectionPool) & success;
            } else {
                // Запись есть -- решение об апгрейде принимается на основе
                // версии и контрольной суммы.
                success = decideToUpgrade(g, gi, connectionPool) & success;
            }
        }
        if (!success) {
            throw new CelestaException("Not all %s were updated successfully, see %s.%s table data for details.", getSchemasTableName(), sysSchemaName, getSchemasTableName());
        }
    }
}
Also used : VersionString(ru.curs.celesta.score.VersionString) HashMap(java.util.HashMap) Grain(ru.curs.celesta.score.Grain) ArrayList(java.util.ArrayList) VersionString(ru.curs.celesta.score.VersionString) ParseException(ru.curs.celesta.score.ParseException) CelestaException(ru.curs.celesta.CelestaException)

Example 2 with Grain

use of ru.curs.celesta.score.Grain in project celesta by CourseOrchestra.

the class FirebirdAdaptor method processDefaults.

private void processDefaults(Connection conn, Column<?> c, DbColumnInfo dbColumnInfo) throws SQLException {
    String defaultValue = null;
    TableElement te = c.getParentTable();
    Grain g = te.getGrain();
    String sql = String.format("SELECT r.RDB$DEFAULT_SOURCE AS column_default_value%n" + "   FROM RDB$RELATION_FIELDS r%n" + "   WHERE r.RDB$RELATION_NAME='%s_%s' AND r.RDB$FIELD_NAME = '%s'", c.getParentTable().getGrain().getName(), c.getParentTable().getName(), c.getName());
    try (ResultSet rs = SqlUtils.executeQuery(conn, sql)) {
        rs.next();
        String defaultSource = rs.getString(1);
        if (defaultSource == null) {
            if (IntegerColumn.class.equals(dbColumnInfo.getType())) {
                String triggerName = SchemalessFunctions.generateSequenceTriggerName((IntegerColumn) c);
                sql = String.format("SELECT proc.RDB$DEPENDED_ON_NAME %n " + "FROM RDB$DEPENDENCIES tr%n " + "JOIN RDB$DEPENDENCIES proc ON tr.RDB$DEPENDED_ON_NAME = proc.RDB$DEPENDENT_NAME%n " + "WHERE tr.RDB$DEPENDENT_NAME = '%s' AND tr.RDB$DEPENDENT_TYPE = 2 " + "AND tr.RDB$DEPENDED_ON_TYPE = 5%n " + "AND proc.RDB$DEPENDENT_TYPE = 5 AND proc.RDB$DEPENDED_ON_TYPE = 14", triggerName);
                try (ResultSet sequenceRs = SqlUtils.executeQuery(conn, sql)) {
                    if (sequenceRs.next()) {
                        String sequenceName = sequenceRs.getString(1).trim();
                        defaultValue = "NEXTVAL(" + // TODO: score sequence name could be spoiled here because of name limitation
                        sequenceName.replace(g.getName() + "_", "") + ")";
                    }
                }
            }
        } else {
            defaultValue = defaultSource.replace("default", "").trim();
            if (BooleanColumn.class.equals(dbColumnInfo.getType())) {
                defaultValue = "0".equals(defaultValue) ? "'FALSE'" : "'TRUE'";
            } else if (DateTimeColumn.class.equals(dbColumnInfo.getType())) {
                if (FireBirdConstants.CURRENT_TIMESTAMP.equalsIgnoreCase(defaultValue)) {
                    defaultValue = "GETDATE()";
                } else {
                    Matcher m = DATE_PATTERN.matcher(defaultValue);
                    if (m.find()) {
                        defaultValue = String.format("'%s%s%s'", m.group(3), m.group(2), m.group(1));
                    }
                }
            } else if (BinaryColumn.class.equals(dbColumnInfo.getType())) {
                Matcher m = HEX_STRING.matcher(defaultValue);
                if (m.find()) {
                    defaultValue = "0x" + m.group(1);
                }
            }
        }
    }
    if (defaultValue != null) {
        dbColumnInfo.setDefaultValue(defaultValue);
    }
}
Also used : Matcher(java.util.regex.Matcher) Grain(ru.curs.celesta.score.Grain) ResultSet(java.sql.ResultSet) DateTimeColumn(ru.curs.celesta.score.DateTimeColumn) TableElement(ru.curs.celesta.score.TableElement)

Example 3 with Grain

use of ru.curs.celesta.score.Grain in project celesta by CourseOrchestra.

the class OraAdaptor method processDefaults.

private void processDefaults(Connection conn, Column<?> c, DbColumnInfo result) throws SQLException {
    ResultSet rs;
    TableElement te = c.getParentTable();
    Grain g = te.getGrain();
    PreparedStatement getDefault = conn.prepareStatement(String.format("select DATA_DEFAULT from DBA_TAB_COLUMNS where " + "owner = sys_context('userenv','session_user') " + "and TABLE_NAME = '%s_%s' and COLUMN_NAME = '%s'", g.getName(), te.getName(), c.getName()));
    try {
        rs = getDefault.executeQuery();
        if (!rs.next()) {
            return;
        }
        String body = rs.getString(1);
        if (body == null || "null".equalsIgnoreCase(body)) {
            if (c instanceof IntegerColumn) {
                IntegerColumn ic = (IntegerColumn) c;
                String sequenceTriggerName = generateSequenceTriggerName(ic);
                String sql = String.format("SELECT REFERENCED_NAME FROM USER_DEPENDENCIES " + " WHERE NAME = '%s' " + " AND TYPE = 'TRIGGER' " + " AND REFERENCED_TYPE = 'SEQUENCE'", sequenceTriggerName);
                try (Statement stmt = conn.createStatement();
                    ResultSet sequenceRs = stmt.executeQuery(sql)) {
                    if (sequenceRs.next()) {
                        String sequenceName = sequenceRs.getString(1);
                        body = "NEXTVAL(" + sequenceName.replace(g.getName() + "_", "") + ")";
                    } else {
                        return;
                    }
                }
            } else {
                return;
            }
        }
        if (BooleanColumn.class == result.getType()) {
            body = "0".equals(body.trim()) ? "'FALSE'" : "'TRUE'";
        } else if (DateTimeColumn.class == result.getType()) {
            if (body.toLowerCase().contains("sysdate")) {
                body = "GETDATE()";
            } else {
                Matcher m = DATE_PATTERN.matcher(body);
                if (m.find()) {
                    body = String.format("'%s%s%s'", m.group(1), m.group(2), m.group(3));
                }
            }
        } else if (BinaryColumn.class == result.getType()) {
            Matcher m = HEX_STRING.matcher(body);
            if (m.find()) {
                body = "0x" + m.group(1);
            }
        } else {
            body = body.trim();
        }
        result.setDefaultValue(body);
    } finally {
        getDefault.close();
    }
}
Also used : IntegerColumn(ru.curs.celesta.score.IntegerColumn) Matcher(java.util.regex.Matcher) Grain(ru.curs.celesta.score.Grain) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) DateTimeColumn(ru.curs.celesta.score.DateTimeColumn) ZonedDateTimeColumn(ru.curs.celesta.score.ZonedDateTimeColumn) TableElement(ru.curs.celesta.score.TableElement)

Example 4 with Grain

use of ru.curs.celesta.score.Grain in project celesta by CourseOrchestra.

the class CursorGenerator method calcSourcePackage.

static String calcSourcePackage(GrainElement ge, String scorePath) {
    String result;
    Grain g = ge.getGrain();
    if (g.getName().equals(g.getScore().getSysSchemaName())) {
        result = "ru.curs.celesta.syscursors";
    } else {
        String grainPartRelativePath = new FileResource(new File(scorePath)).getRelativePath(ge.getGrainPart().getSource());
        result = Optional.of(grainPartRelativePath.lastIndexOf(File.separatorChar)).filter(i -> i >= 0).map(i -> grainPartRelativePath.substring(0, i).replace(File.separator, ".")).orElse("");
        if (result.startsWith(".")) {
            result = result.substring(1);
        }
    }
    return result;
}
Also used : BasicCursor(ru.curs.celesta.dbutils.BasicCursor) Arrays(java.util.Arrays) Modifier(javax.lang.model.element.Modifier) CelestaException(ru.curs.celesta.CelestaException) ZonedDateTime(java.time.ZonedDateTime) ClassName(com.squareup.javapoet.ClassName) SequenceElement(ru.curs.celesta.score.SequenceElement) Grain(ru.curs.celesta.score.Grain) Parameter(ru.curs.celesta.score.Parameter) ColumnMeta(ru.curs.celesta.score.ColumnMeta) Generated(javax.annotation.Generated) StringColumn(ru.curs.celesta.score.StringColumn) ResultSet(java.sql.ResultSet) Map(java.util.Map) ICelesta(ru.curs.celesta.ICelesta) ZoneOffset(java.time.ZoneOffset) DataGrainElement(ru.curs.celesta.score.DataGrainElement) CelestaGenerated(ru.curs.celesta.dbutils.CelestaGenerated) ParameterSpec(com.squareup.javapoet.ParameterSpec) CallContext(ru.curs.celesta.CallContext) TimeZone(java.util.TimeZone) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) Set(java.util.Set) Column(ru.curs.celesta.score.Column) Collectors(java.util.stream.Collectors) JavaFile(com.squareup.javapoet.JavaFile) Objects(java.util.Objects) List(java.util.List) ViewCursor(ru.curs.celesta.dbutils.ViewCursor) TriggerType(ru.curs.celesta.event.TriggerType) BasicTable(ru.curs.celesta.score.BasicTable) GrainElement(ru.curs.celesta.score.GrainElement) BasicDataAccessor(ru.curs.celesta.dbutils.BasicDataAccessor) TypeName(com.squareup.javapoet.TypeName) Optional(java.util.Optional) IntegerColumn(ru.curs.celesta.score.IntegerColumn) MaterializedViewCursor(ru.curs.celesta.dbutils.MaterializedViewCursor) ZonedDateTimeColumn(ru.curs.celesta.score.ZonedDateTimeColumn) FieldSpec(com.squareup.javapoet.FieldSpec) TableElement(ru.curs.celesta.score.TableElement) LocalDateTime(java.time.LocalDateTime) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) Cursor(ru.curs.celesta.dbutils.Cursor) HashMap(java.util.HashMap) View(ru.curs.celesta.score.View) ReadOnlyTable(ru.curs.celesta.score.ReadOnlyTable) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) SQLException(java.sql.SQLException) Calendar(java.util.Calendar) Sequence(ru.curs.celesta.dbutils.Sequence) BinaryColumn(ru.curs.celesta.score.BinaryColumn) ParameterizedView(ru.curs.celesta.score.ParameterizedView) CodeBlock(com.squareup.javapoet.CodeBlock) LinkedHashSet(java.util.LinkedHashSet) Iterator(java.util.Iterator) MethodSpec(com.squareup.javapoet.MethodSpec) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) IOException(java.io.IOException) CursorIterator(ru.curs.celesta.dbutils.CursorIterator) TypeSpec(com.squareup.javapoet.TypeSpec) ParameterizedViewCursor(ru.curs.celesta.dbutils.ParameterizedViewCursor) MaterializedView(ru.curs.celesta.score.MaterializedView) Table(ru.curs.celesta.score.Table) File(java.io.File) Consumer(java.util.function.Consumer) AnnotationSpec(com.squareup.javapoet.AnnotationSpec) VersionedElement(ru.curs.celesta.score.VersionedElement) DateTimeFormatter(java.time.format.DateTimeFormatter) NamedElement(ru.curs.celesta.score.NamedElement) FileResource(ru.curs.celesta.score.io.FileResource) ReadOnlyTableCursor(ru.curs.celesta.dbutils.ReadOnlyTableCursor) Collections(java.util.Collections) ArrayTypeName(com.squareup.javapoet.ArrayTypeName) Grain(ru.curs.celesta.score.Grain) FileResource(ru.curs.celesta.score.io.FileResource) JavaFile(com.squareup.javapoet.JavaFile) File(java.io.File)

Example 5 with Grain

use of ru.curs.celesta.score.Grain in project celesta by CourseOrchestra.

the class AbstractAdaptorTest method testCreateAndAlterSequence.

@Test
void testCreateAndAlterSequence() throws Exception {
    Grain g = score.getGrain(GRAIN_NAME);
    SequenceElement sequence = g.getElement("testSequence", SequenceElement.class);
    if (dba.sequenceExists(conn, g.getName(), sequence.getName()))
        dba.dropSequence(conn, sequence);
    // Sequence not exists
    assertFalse(dba.sequenceExists(conn, g.getName(), sequence.getName()));
    dba.createSequence(conn, sequence);
    assertTrue(dba.sequenceExists(conn, g.getName(), sequence.getName()));
    DbSequenceInfo sequenceInfo = dba.getSequenceInfo(conn, sequence);
    assertFalse(sequenceInfo.reflects(sequence));
    assertAll(() -> assertEquals(1L, sequenceInfo.getIncrementBy()), () -> assertEquals(5L, sequenceInfo.getMinValue()), () -> assertEquals(Long.MAX_VALUE, sequenceInfo.getMaxValue()), () -> assertEquals(false, sequenceInfo.isCycle()));
    assertEquals(5, dba.nextSequenceValue(conn, sequence));
    assertEquals(6, dba.nextSequenceValue(conn, sequence));
    // Modifying of increment by
    sequence.getArguments().put(SequenceElement.Argument.INCREMENT_BY, 2L);
    assertTrue(sequenceInfo.reflects(sequence));
    dba.alterSequence(conn, sequence);
    DbSequenceInfo sequenceInfo2 = dba.getSequenceInfo(conn, sequence);
    assertFalse(sequenceInfo2.reflects(sequence));
    assertAll(() -> assertEquals(2L, sequenceInfo2.getIncrementBy()), () -> assertEquals(5L, sequenceInfo2.getMinValue()), () -> assertEquals(Long.MAX_VALUE, sequenceInfo2.getMaxValue()), () -> assertEquals(false, sequenceInfo2.isCycle()));
    // Altering to short cycle
    sequence.getArguments().put(SequenceElement.Argument.INCREMENT_BY, 1L);
    sequence.getArguments().put(SequenceElement.Argument.MINVALUE, 5L);
    sequence.getArguments().put(SequenceElement.Argument.MAXVALUE, 7L);
    sequence.getArguments().put(SequenceElement.Argument.CYCLE, true);
    assertTrue(sequenceInfo.reflects(sequence));
    dba.alterSequence(conn, sequence);
    DbSequenceInfo sequenceInfo3 = dba.getSequenceInfo(conn, sequence);
    assertFalse(sequenceInfo3.reflects(sequence));
    assertAll(() -> assertEquals(1L, sequenceInfo3.getIncrementBy()), () -> assertEquals(5L, sequenceInfo3.getMinValue()), () -> assertEquals(7L, sequenceInfo3.getMaxValue()), () -> assertEquals(true, sequenceInfo3.isCycle()));
    dba.dropSequence(conn, sequence);
}
Also used : DbSequenceInfo(ru.curs.celesta.dbutils.meta.DbSequenceInfo) Grain(ru.curs.celesta.score.Grain) SequenceElement(ru.curs.celesta.score.SequenceElement) Test(org.junit.jupiter.api.Test)

Aggregations

Grain (ru.curs.celesta.score.Grain)24 Test (org.junit.jupiter.api.Test)14 CelestaException (ru.curs.celesta.CelestaException)12 SequenceElement (ru.curs.celesta.score.SequenceElement)12 BasicTable (ru.curs.celesta.score.BasicTable)11 SQLException (java.sql.SQLException)9 ParseException (ru.curs.celesta.score.ParseException)9 IOException (java.io.IOException)7 ResultSet (java.sql.ResultSet)7 PreparedStatement (java.sql.PreparedStatement)6 ArrayList (java.util.ArrayList)6 MaterializedView (ru.curs.celesta.score.MaterializedView)6 ParameterizedView (ru.curs.celesta.score.ParameterizedView)5 Connection (java.sql.Connection)4 Statement (java.sql.Statement)4 AbstractScore (ru.curs.celesta.score.AbstractScore)4 DateTimeColumn (ru.curs.celesta.score.DateTimeColumn)4 File (java.io.File)3 LocalDateTime (java.time.LocalDateTime)3 HashMap (java.util.HashMap)3