private int writeImplInner()

in src/main/java/org/opensearch/performanceanalyzer/rca/persistence/SQLitePersistor.java [692:798]


    private <T> int writeImplInner(T obj)
            throws IllegalStateException, IllegalAccessException, InvocationTargetException,
                    SQLException, NoSuchMethodException {
        Class<?> clz = obj.getClass();
        String tableName = getTableNameFromClassName(clz);
        Table<Record> table = DSL.table(tableName);

        // If there exists a table with the same name as the SimpleName of this class, make sure
        // that the persisted class is same as this.
        // This is to avoid cases of trying to persist classes from two different packages with the
        // same name.
        if (jooqTableColumns.containsKey(tableName)) {
            // There can be a case where two distinct classes with the same SimpleName, might want
            // to persist themselves. In this case, we should keep things simple and throw an error.
            Class<?> alreadyStoredTableClass = tableNameToJavaClassMap.get(tableName);
            Objects.requireNonNull(
                    alreadyStoredTableClass,
                    "A table exists with this name but the table is not mapped to a Java class.");
            if (alreadyStoredTableClass != clz) {
                throw new IllegalStateException(
                        "There is already a table in the Database with the same name. It belongs to the class: '"
                                + alreadyStoredTableClass
                                + "'. Please consider re-naming your classes.");
            }
            Objects.requireNonNull(
                    fieldGetterSetterPairsMap.get(clz),
                    "Because the class is already persisted once, we should have the "
                            + "mapping for field to their corresponding getter and setters.");
        } else {
            createFieldRegistry(clz);
        }

        Map<java.lang.reflect.Field, GetterSetterPairs> fieldToGetterSetterMap =
                fieldGetterSetterPairsMap.get(clz);
        List<Field<?>> fields = new ArrayList<>();
        List<Object> values = new ArrayList<>();

        for (Map.Entry<java.lang.reflect.Field, GetterSetterPairs> entry :
                fieldToGetterSetterMap.entrySet()) {
            Method getter = entry.getValue().getter;
            java.lang.reflect.Field classField = entry.getKey();

            String columnName = classField.getName();
            Class<?> retType = getter.getReturnType();

            if (classField.isAnnotationPresent(RefColumn.class)) {
                columnName = NESTED_OBJECT_COLUMN_PREFIX + columnName;
                if (Collection.class.isAssignableFrom(retType)) {
                    ColumnValuePair columnValuePair =
                            writeCollectionReferenceColumn(classField, getter, obj);
                    fields.add(columnValuePair.field);
                    values.add(columnValuePair.value);
                } else {
                    // This is a user-defined class Type
                    int id = writeImplInner(retType.cast(getter.invoke(obj)));
                    // Although the ID is long, we are persisting it as string because if there are
                    // multiple rows in the child table, that refer to
                    // the parent table row, then, the parent table should have a list of them. IN
                    // which case the value stored in the column will be
                    // of the form: [id1, id2, ..].
                    fields.add(DSL.field(DSL.name(columnName), Integer.class));
                    values.add(id);
                }
            } else if (retType.isPrimitive()) {
                fields.add(DSL.field(DSL.name(columnName), retType));
                values.add(getter.invoke(obj));
            } else if (retType == String.class) {
                fields.add(DSL.field(DSL.name(columnName), String.class));
                values.add(getter.invoke(obj));
            }
        }

        if (fields.size() == 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("Class ")
                    .append(clz.getSimpleName())
                    .append(" was asked to be persisted but there are no fields with annotations: ")
                    .append(ValueColumn.class.getSimpleName())
                    .append(" or ")
                    .append(RefColumn.class.getSimpleName());
            throw new IllegalStateException(sb.toString());
        }

        // If table does not exist, try to create one.
        if (!jooqTableColumns.containsKey(tableName)) {
            createTable(tableName, fields);
            tableNameToJavaClassMap.put(tableName, obj.getClass());
        }

        try {
            int ret = create.insertInto(table).columns(fields).values(values).execute();
        } catch (Exception e) {
            LOG.error("Inserting row '{}' into table '{}' failed", values, tableName, e);
            throw new SQLException(e);
        }
        int lastRowId = -1;
        String sqlQuery = "SELECT " + LAST_INSERT_ROWID;

        try {
            lastRowId = create.fetch(sqlQuery).get(0).get(LAST_INSERT_ROWID, Integer.class);
        } catch (Exception e) {
            LOG.error("Failed to insert into the table {}", table, e);
            throw new SQLException(e);
        }
        LOG.debug("most recently inserted primary key = {}", lastRowId);
        return lastRowId;
    }