class PrimaryKeySnapshotGenerator extends JdbcSnapshotGenerator {

    public PrimaryKeySnapshotGenerator() {
        super(PrimaryKey.class, new Class[]{Table.class});
    }

    @Override
    protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws
            DatabaseException, InvalidExampleException {
        Database database = snapshot.getDatabase();
        Schema schema = example.getSchema();
        String searchTableName = null;
        if (((PrimaryKey) example).getTable() != null) {
            searchTableName = ((PrimaryKey) example).getTable().getName();
            searchTableName = database.correctObjectName(searchTableName, Table.class);
        }

        List<CachedRow> rs;
        try {
            JdbcDatabaseSnapshot.CachingDatabaseMetaData metaData = ((JdbcDatabaseSnapshot) snapshot)
                    .getMetaDataFromCache();
            rs = metaData.getPrimaryKeys(((AbstractJdbcDatabase) database).getJdbcCatalogName(schema), (
                    (AbstractJdbcDatabase) database).getJdbcSchemaName(schema), searchTableName);
            PrimaryKey returnKey = null;
            for (CachedRow row : rs) {
                if ((example.getName() != null) && !example.getName().equalsIgnoreCase(row.getString("PK_NAME"))) {
                    continue;
                }
                String columnName = cleanNameFromDatabase(row.getString("COLUMN_NAME"), database);
                short position = row.getShort("KEY_SEQ");

                if (returnKey == null) {
                    returnKey = new PrimaryKey();
                    CatalogAndSchema tableSchema = ((AbstractJdbcDatabase) database).getSchemaFromJdbcInfo(
                            row.getString("TABLE_CAT"), row.getString("TABLE_SCHEM")
                    );
                    returnKey.setTable((Table) new Table().setName(row.getString("TABLE_NAME"))
                            .setSchema(new Schema(tableSchema.getCatalogName(), tableSchema.getSchemaName())));
                    returnKey.setName(row.getString("PK_NAME"));
                }

                String ascOrDesc = row.getString("ASC_OR_DESC");
                Boolean descending = null;
                if("D".equals(ascOrDesc)) {
                    descending = Boolean.TRUE;
                } else {
                    if ("A".equals(ascOrDesc)) {
                        descending = Boolean.FALSE;
                    }
                }
                boolean computed = descending != null && descending;
                returnKey.addColumn(position - 1, new Column(columnName)
                        .setDescending(descending)
                        .setComputed(computed)
                        .setRelation(((PrimaryKey) example).getTable())
                );
                setValidateOptionIfAvailable(database, returnKey, row);
            }

            if (returnKey != null) {
                Index exampleIndex = new Index().setRelation(returnKey.getTable());
                exampleIndex.setColumns(returnKey.getColumns());
                returnKey.setBackingIndex(exampleIndex);
            }
            return returnKey;
        } catch (SQLException e) {
            throw new DatabaseException(e);
        }
    }

    /**
     * Method to map 'validate' option for PK.
     *
     * @param database - DB where PK will be created
     * @param primaryKey - PK object to persist validate option
     * @param cachedRow - it's a cache-map to get metadata about PK
     */
    private void setValidateOptionIfAvailable(Database database, PrimaryKey primaryKey, CachedRow cachedRow) {
        if (!(database instanceof OracleDatabase)) {
            return;
        }
        final String constraintValidate = cachedRow.getString("VALIDATED");
        final String VALIDATE = "VALIDATED";
        if (constraintValidate!=null && !constraintValidate.isEmpty()) {
            primaryKey.setShouldValidate(VALIDATE.equals(cleanNameFromDatabase(constraintValidate.trim(), database)));
        }
    }

    @Override
    protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) throws DatabaseException {<FILL_FUNCTION_BODY>}
}

        if (!snapshot.getSnapshotControl().shouldInclude(PrimaryKey.class) || !snapshot.getDatabase().supports(PrimaryKey.class)) {
            return;
        }

        if (foundObject instanceof Table) {
            Table table = (Table) foundObject;
            Database database = snapshot.getDatabase();
            Schema schema = table.getSchema();

            List<CachedRow> rs;
            try {
                JdbcDatabaseSnapshot.CachingDatabaseMetaData metaData = ((JdbcDatabaseSnapshot) snapshot)
                        .getMetaDataFromCache();
                rs = metaData.getPrimaryKeys(((AbstractJdbcDatabase) database).getJdbcCatalogName(schema), (
                        (AbstractJdbcDatabase) database).getJdbcSchemaName(schema), table.getName());
                if (!rs.isEmpty()) {
                    PrimaryKey primaryKey = new PrimaryKey().setName(rs.get(0).getString("PK_NAME"));
                    primaryKey.setTable((Table) foundObject);
                    if (!database.isSystemObject(primaryKey)) {
                        table.setPrimaryKey(primaryKey.setTable(table));
                    }
                }
            } catch (SQLException e) {
                throw new DatabaseException(e);
            }

        }
    
<methods>public void addStatusListener(liquibase.diff.DiffStatusListener) ,public Class<? extends liquibase.structure.DatabaseObject>[] addsTo() ,public int getPriority(Class<? extends liquibase.structure.DatabaseObject>, liquibase.database.Database) ,public Class<? extends liquibase.snapshot.SnapshotGenerator>[] replaces() ,public liquibase.structure.DatabaseObject snapshot(liquibase.structure.DatabaseObject, liquibase.snapshot.DatabaseSnapshot, liquibase.snapshot.SnapshotGeneratorChain) throws liquibase.exception.DatabaseException, liquibase.snapshot.InvalidExampleException<variables>private Class<? extends liquibase.structure.DatabaseObject>[] addsTo,private final non-sealed Class<? extends liquibase.structure.DatabaseObject> defaultFor,private final Set<liquibase.diff.DiffStatusListener> statusListeners