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 009import com.fasterxml.jackson.annotation.JsonInclude; 010import com.fasterxml.jackson.databind.ObjectMapper; 011import com.fasterxml.jackson.databind.PropertyNamingStrategies; 012 013import java.util.Locale; 014 015/** 016 * Parameters for {@code DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA}. 017 * <p> 018 * These parameters control how Select AI samples source table data, uses table 019 * statistics, and schedules parallel requests when generating synthetic data. 020 * 021 * <p> 022 * The SDK performs basic, deterministic validation for values that can be 023 * validated independently of Oracle Database. In particular, 024 * {@code sampleRows} must be between 0 and 100, inclusive, when specified, 025 * and {@code priority} must be one of {@code HIGH}, {@code MEDIUM}, or 026 * {@code LOW}. Invalid values detected by the SDK result in an 027 * {@link IllegalArgumentException}. 028 * 029 * <p> 030 * Database-specific, database-version-specific, and other semantic validation 031 * is delegated to {@code DBMS_CLOUD_AI} and Oracle Database. Therefore, a 032 * parameter value that passes SDK validation may still be rejected by the 033 * database based on the requested synthetic-data operation or other 034 * database-side requirements. 035 * 036 * @see <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-ai-package.html#optional-parameters"> 037 * DBMS_CLOUD_AI synthetic data parameters</a> 038 */ 039public final class SyntheticDataParams { 040 041 /** Number of table rows sampled to guide synthetic data generation. */ 042 private final Integer sampleRows; 043 044 /** Whether table statistics are used during synthetic data generation. */ 045 private final Boolean tableStatistics; 046 047 /** 048 * Priority used to determine the parallelism of synthetic-data generation 049 * requests. Supported values are {@code HIGH}, {@code MEDIUM}, and {@code LOW}. 050 */ 051 private final String priority; 052 053 /** Whether table comments are used as context during synthetic data generation. */ 054 private final Boolean comments; 055 056 private SyntheticDataParams(Builder builder) { 057 this.sampleRows = builder.sampleRows; 058 this.tableStatistics = builder.tableStatistics; 059 this.priority = builder.priority; 060 this.comments = builder.comments; 061 } 062 063 /** 064 * Returns the number of table rows sampled to guide synthetic data generation. 065 * 066 * @return sample-rows value, or {@code null} when unset 067 */ 068 public Integer getSampleRows() { 069 return sampleRows; 070 } 071 072 /** 073 * Returns whether table statistics are used during synthetic data generation. 074 * 075 * @return table-statistics flag, or {@code null} when unset 076 */ 077 public Boolean getTableStatistics() { 078 return tableStatistics; 079 } 080 081 /** 082 * Returns the priority used for synthetic data generation. 083 * 084 * @return priority value ({@code HIGH}, {@code MEDIUM}, or {@code LOW}), 085 * or {@code null} when unset 086 */ 087 public String getPriority() { 088 return priority; 089 } 090 091 /** 092 * Returns whether table comments are used as generation context. 093 * 094 * @return comments flag, or {@code null} when unset 095 */ 096 public Boolean getComments() { 097 return comments; 098 } 099 100 /** 101 * Serializes the parameter payload using the snake_case names expected by 102 * {@code DBMS_CLOUD_AI}. 103 * 104 * @return JSON representation of this {@code SyntheticDataParams} 105 * @throws IllegalStateException if serialization fails 106 */ 107 public String toJson() { 108 try { 109 ObjectMapper mapper = new ObjectMapper(); 110 mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); 111 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 112 return mapper.writeValueAsString(this); 113 } catch (Exception e) { 114 throw new IllegalStateException("Failed to serialize SyntheticDataParams", e); 115 } 116 } 117 118 /** 119 * Creates a builder for synthetic data generation parameters. 120 * 121 * @return new builder for constructing {@link SyntheticDataParams} 122 */ 123 public static Builder builder() { 124 return new Builder(); 125 } 126 127 /** 128 * Priority values accepted by synthetic data generation parameters. 129 */ 130 public enum Priority { 131 /** High priority synthetic-data generation. */ 132 HIGH, 133 /** Medium priority synthetic-data generation. */ 134 MEDIUM, 135 /** Low priority synthetic-data generation. */ 136 LOW 137 } 138 139 /** 140 * Builder for {@link SyntheticDataParams}. 141 */ 142 public static final class Builder { 143 /** Creates an empty builder. */ 144 public Builder() { 145 } 146 147 /** Sample rows value being assembled. */ 148 private Integer sampleRows; 149 /** Table statistics flag being assembled. */ 150 private Boolean tableStatistics; 151 /** Priority value being assembled. */ 152 private String priority; 153 /** Comments flag being assembled. */ 154 private Boolean comments; 155 156 /** 157 * Sets the number of table rows sampled to guide synthetic data generation. 158 * 159 * <p>The value must be between 0 and 100, inclusive, when specified. 160 * A value of 0 indicates that no sample rows are used.</p> 161 * 162 * @param sampleRows sample-row value, from 0 through 100, or {@code null} 163 * when unset 164 * @return this builder instance 165 * @throws IllegalArgumentException if {@code sampleRows} is less than 0 166 * or greater than 100 167 */ 168 public Builder sampleRows(Integer sampleRows) { 169 if (sampleRows != null && (sampleRows < 0 || sampleRows > 100)) { 170 throw new IllegalArgumentException("sampleRows must be between 0 and 100"); 171 } 172 this.sampleRows = sampleRows; 173 return this; 174 } 175 176 /** 177 * Sets whether table statistics should be used during synthetic data 178 * generation. 179 * 180 * @param tableStatistics whether table statistics should be used, or 181 * {@code null} when unset 182 * @return this builder instance 183 */ 184 public Builder tableStatistics(Boolean tableStatistics) { 185 this.tableStatistics = tableStatistics; 186 return this; 187 } 188 189 /** 190 * Sets the priority used for synthetic data generation. 191 * 192 * <p>The supported values are {@code HIGH}, {@code MEDIUM}, and 193 * {@code LOW}. The comparison is case-insensitive; the value stored by the 194 * builder is normalized to upper case.</p> 195 * 196 * @param priority priority value ({@code HIGH}, {@code MEDIUM}, or 197 * {@code LOW}), or {@code null} when unset 198 * @return this builder instance 199 * @throws IllegalArgumentException if {@code priority} is not one of the 200 * supported values 201 */ 202 public Builder priority(String priority) { 203 if (priority != null) { 204 String p = priority.trim().toUpperCase(Locale.ROOT); 205 if (!p.equals("HIGH") && !p.equals("MEDIUM") && !p.equals("LOW")) { 206 throw new IllegalArgumentException("priority must be HIGH, MEDIUM, or LOW"); 207 } 208 this.priority = p; 209 } else { 210 this.priority = null; 211 } 212 return this; 213 } 214 215 /** 216 * Sets the priority used for synthetic data generation. 217 * 218 * @param priority priority value, or {@code null} when unset 219 * @return this builder instance 220 */ 221 public Builder priority(Priority priority) { 222 this.priority = priority == null ? null : priority.name(); 223 return this; 224 } 225 226 /** 227 * Sets whether table comments should be used as context during synthetic 228 * data generation. 229 * 230 * @param comments whether comments should be used, or {@code null} when unset 231 * @return this builder instance 232 */ 233 public Builder comments(Boolean comments) { 234 this.comments = comments; 235 return this; 236 } 237 238 /** 239 * Builds the synthetic data parameter payload. 240 * 241 * <p>SDK-level validation is applied when individual values are set. 242 * Database-specific and semantic validation remains delegated to 243 * {@code DBMS_CLOUD_AI} and Oracle Database.</p> 244 * 245 * @return immutable {@link SyntheticDataParams} instance built from the 246 * current builder state 247 */ 248 public SyntheticDataParams build() { 249 return new SyntheticDataParams(this); 250 } 251 } 252}