001package gudusoft.gsqlparser.catalog.input.readers;
002
003import gudusoft.gsqlparser.catalog.input.CatalogInputException;
004import gudusoft.gsqlparser.catalog.input.CatalogInputKind;
005import gudusoft.gsqlparser.catalog.input.CatalogInputReader;
006import gudusoft.gsqlparser.catalog.input.CatalogInputReaderFactory;
007import gudusoft.gsqlparser.catalog.input.CatalogInputSource;
008import gudusoft.gsqlparser.catalog.input.CatalogLoadOptions;
009import gudusoft.gsqlparser.catalog.input.model.UnifiedCatalogModel;
010
011/**
012 * Pass-through reader for {@link CatalogInputKind#IN_MEMORY} sources: the source already
013 * carries a {@link UnifiedCatalogModel}, so {@code read} returns it directly.
014 *
015 * <p>Plan §6 / §7.1. Used by tests and demos that build a catalog programmatically.</p>
016 */
017public final class MemoryCatalogInputReader implements CatalogInputReader {
018
019    public MemoryCatalogInputReader() {
020    }
021
022    @Override
023    public CatalogInputKind kind() {
024        return CatalogInputKind.IN_MEMORY;
025    }
026
027    @Override
028    public boolean supports(CatalogInputSource source, CatalogLoadOptions options) {
029        if (source == null) {
030            return false;
031        }
032        // Require an actual model — a path/bytes/reader source mistakenly tagged with
033        // declaredKind=IN_MEMORY isn't readable here, and CatalogInputReaders.forSource
034        // would otherwise pick this reader and then fail on read().
035        return source.inMemoryModel() != null;
036    }
037
038    @Override
039    public UnifiedCatalogModel read(CatalogInputSource source, CatalogLoadOptions options)
040            throws CatalogInputException {
041        if (source == null) {
042            throw new CatalogInputException("MemoryCatalogInputReader: source is required");
043        }
044        UnifiedCatalogModel model = source.inMemoryModel();
045        if (model == null) {
046            throw new CatalogInputException(
047                "MemoryCatalogInputReader: source has no in-memory model");
048        }
049        return model;
050    }
051
052    /** ServiceLoader-discoverable factory. */
053    public static final class Factory implements CatalogInputReaderFactory {
054
055        public Factory() {
056            // Required no-arg constructor for ServiceLoader.
057        }
058
059        @Override
060        public CatalogInputKind kind() {
061            return CatalogInputKind.IN_MEMORY;
062        }
063
064        @Override
065        public CatalogInputReader create() {
066            return new MemoryCatalogInputReader();
067        }
068    }
069}