001/*
002 * Copyright (c) 2026, Oracle and/or its affiliates.
003 *
004 * Licensed under the Universal Permissive License Version 1.0 as shown at
005 * https://oss.oracle.com/licenses/upl/
006 */
007package com.oracle.database.selectai.model;
008
009/**
010 * Request object for generating synthetic data for a single database object.
011 * <p>
012 * This request groups the target database object, owner/schema, requested
013 * record count, user guidance, and synthetic-data generation parameters into
014 * one immutable request.
015 *
016 * <p>
017 * The SDK performs basic, deterministic validation where the constraint can
018 * be evaluated independently of Oracle Database. In particular, the
019 * {@code objectName} must not be null or blank, and {@code recordCount}, when
020 * specified, must be greater than zero. Invalid values detected by the SDK
021 * result in an {@link IllegalArgumentException}.
022 *
023 * <p>
024 * Database-specific, database-version-specific, and other semantic validation
025 * is delegated to {@code DBMS_CLOUD_AI} and Oracle Database. Therefore, a
026 * request that passes SDK validation may still be rejected by the database
027 * based on the requested synthetic-data operation or other database-side
028 * requirements.
029 *
030 * @see <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-ai-package.html#parameters-18">
031 *      DBMS_CLOUD_AI synthetic data parameters</a>
032 */
033public final class SyntheticDataSingleRequest {
034
035    /** Target database object name. */
036    private final String objectName;
037
038    /** Database user/schema associated with the target object. */
039    private final String ownerName;
040
041    /** Number of records requested for generation. */
042    private final Integer recordCount;
043
044    /** User guidance for synthetic data generation. */
045    private final String userPrompt;
046
047    /** Parameters controlling synthetic data generation. */
048    private final SyntheticDataParams params;
049
050    private SyntheticDataSingleRequest(Builder builder) {
051        this.objectName = builder.objectName;
052        this.ownerName = builder.ownerName;
053        this.recordCount = builder.recordCount;
054        this.userPrompt = builder.userPrompt;
055        this.params = builder.params;
056    }
057
058    /**
059     * Returns the target database object name.
060     *
061     * @return target object name
062     */
063    public String getObjectName() {
064        return objectName;
065    }
066
067    /**
068     * Returns the database user/schema associated with the target object.
069     *
070     * @return owner/schema name, or {@code null} when not set
071     */
072    public String getOwnerName() {
073        return ownerName;
074    }
075
076    /**
077     * Returns the requested number of records to generate.
078     *
079     * @return record count, or {@code null} when not set
080     */
081    public Integer getRecordCount() {
082        return recordCount;
083    }
084
085    /**
086     * Returns user guidance for synthetic data generation.
087     *
088     * @return user prompt, or {@code null} when not set
089     */
090    public String getUserPrompt() {
091        return userPrompt;
092    }
093
094    /**
095     * Returns the synthetic data generation parameters.
096     *
097     * @return generation parameters, or {@code null} when not set
098     */
099    public SyntheticDataParams getParams() {
100        return params;
101    }
102
103    /**
104     * Returns the synthetic data generation parameters serialized as JSON.
105     *
106     * @return JSON representation of the parameters, or {@code null} when
107     *         parameters are not set
108     */
109    public String getParamsJson() {
110        return params == null ? null : params.toJson();
111    }
112
113    /**
114     * Creates a builder for a single-object synthetic data request.
115     *
116     * <p>The SDK validates the target object name when the builder is created.
117     * Database-specific validation of the target object and generation semantics
118     * is delegated to {@code DBMS_CLOUD_AI} and Oracle Database.</p>
119     *
120     * @param objectName target database object name
121     * @return builder initialized with the target object name
122     * @throws IllegalArgumentException if {@code objectName} is null or blank
123     */
124    public static Builder builder(String objectName) {
125        return new Builder(objectName);
126    }
127
128    /**
129     * Builder for {@link SyntheticDataSingleRequest}.
130     */
131    public static final class Builder {
132        /** Required target object name. */
133        private final String objectName;
134        /** Target owner/schema being assembled. */
135        private String ownerName;
136        /** Exact record count being assembled. */
137        private Integer recordCount;
138        /** Generation prompt being assembled. */
139        private String userPrompt;
140        /** Structured generation parameters being assembled. */
141        private SyntheticDataParams params;
142
143        private Builder(String objectName) {
144            if (objectName == null || objectName.isBlank()) {
145                throw new IllegalArgumentException("objectName must not be null or blank");
146            }
147            this.objectName = objectName;
148        }
149
150        /**
151         * Sets the database user/schema associated with the target object.
152         * <p>
153         * Null is sent to the database as SQL NULL. Non-null values, including
154         * blank strings, are preserved as supplied by the caller.
155         *
156         * @param ownerName owner/schema name
157         * @return this builder instance
158         */
159        public Builder ownerName(String ownerName) {
160            this.ownerName = ownerName;
161            return this;
162        }
163
164        /**
165         * Sets the number of records to generate for the target object.
166         *
167         * <p>The value must be greater than zero when specified. Other
168         * synthetic-data-specific semantics are validated by Oracle Database.</p>
169         *
170         * @param recordCount record count, or {@code null} when not set
171         * @return this builder instance
172         * @throws IllegalArgumentException if {@code recordCount} is less than or
173         *         equal to zero
174         */
175        public Builder recordCount(Integer recordCount) {
176            if (recordCount != null && recordCount <= 0) {
177                throw new IllegalArgumentException("recordCount must be greater than 0");
178            }
179            this.recordCount = recordCount;
180            return this;
181        }
182
183        /**
184         * Sets user guidance for synthetic data generation.
185         * <p>
186         * Null is sent to the database as SQL NULL. Non-null values, including
187         * blank strings, are preserved as supplied by the caller.
188         *
189         * @param userPrompt generation guidance
190         * @return this builder instance
191         */
192        public Builder userPrompt(String userPrompt) {
193            this.userPrompt = userPrompt;
194            return this;
195        }
196
197        /**
198         * Sets the synthetic data generation parameters.
199         *
200         * <p>The supplied {@link SyntheticDataParams} instance is expected to have
201         * already applied its SDK-level validation. Database-specific validation is
202         * performed by Oracle Database when the request is executed.</p>
203         *
204         * @param params synthetic data generation parameters
205         * @return this builder instance
206         */
207        public Builder params(SyntheticDataParams params) {
208            this.params = params;
209            return this;
210        }
211
212        /**
213         * Builds the single-object synthetic data request.
214         *
215         * <p>SDK-level validation is applied when the relevant values are set.
216         * Database-specific and operation-specific validation remains delegated to
217         * {@code DBMS_CLOUD_AI} and Oracle Database.</p>
218         *
219         * @return immutable {@link SyntheticDataSingleRequest} instance
220         */
221        public SyntheticDataSingleRequest build() {
222            return new SyntheticDataSingleRequest(this);
223        }
224    }
225}