001/** 002 * Copyright (C) 2006-2022 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.api.record; 017 018import static java.util.Optional.ofNullable; 019 020import java.time.ZonedDateTime; 021import java.util.Collection; 022import java.util.Comparator; 023import java.util.Date; 024import java.util.List; 025import java.util.Optional; 026import java.util.OptionalDouble; 027import java.util.OptionalInt; 028import java.util.OptionalLong; 029 030import org.talend.sdk.component.api.record.Schema.Entry; 031 032public interface Record { 033 034 /** 035 * @return the schema of this record. 036 */ 037 Schema getSchema(); 038 039 /** 040 * Create a Builder with values of the record present in {@link Schema}. 041 * 042 * @param schema new schema 043 * @return a {@link Record.Builder} 044 */ 045 default Builder withNewSchema(Schema schema) { 046 throw new UnsupportedOperationException("#withNewSchema is not implemented"); 047 } 048 049 /** 050 * Access a record field value. 051 * 052 * IMPORTANT: it is always better to use the typed accessors and the optional flavor when the entry is nullable. 053 * 054 * @param expectedType the expected type for the column. 055 * @param name the name of the column. 056 * @param <T> the type of expectedType. 057 * @return the column value. 058 */ 059 <T> T get(Class<T> expectedType, String name); 060 061 /** 062 * See {@link Record#get(Class, String)}. 063 * 064 * @param name entry name. 065 * @return the value of the entry in this record. 066 */ 067 default String getString(final String name) { 068 return get(String.class, name); 069 } 070 071 /** 072 * See {@link Record#get(Class, String)}. 073 * 074 * @param name entry name. 075 * @return the value of the entry in this record. 076 */ 077 default int getInt(final String name) { 078 return get(Integer.class, name); 079 } 080 081 /** 082 * See {@link Record#get(Class, String)}. 083 * 084 * @param name entry name. 085 * @return the value of the entry in this record. 086 */ 087 default long getLong(final String name) { 088 return get(Long.class, name); 089 } 090 091 /** 092 * See {@link Record#get(Class, String)}. 093 * 094 * @param name entry name. 095 * @return the value of the entry in this record. 096 */ 097 default double getDouble(final String name) { 098 return get(Double.class, name); 099 } 100 101 /** 102 * See {@link Record#get(Class, String)}. 103 * 104 * @param name entry name. 105 * @return the value of the entry in this record. 106 */ 107 default float getFloat(final String name) { 108 return get(Float.class, name); 109 } 110 111 /** 112 * See {@link Record#get(Class, String)}. 113 * 114 * @param name entry name. 115 * @return the value of the entry in this record. 116 */ 117 default boolean getBoolean(final String name) { 118 return get(Boolean.class, name); 119 } 120 121 /** 122 * See {@link Record#get(Class, String)}. 123 * 124 * @param name entry name. 125 * @return the value of the entry in this record. 126 */ 127 default byte[] getBytes(final String name) { 128 return get(byte[].class, name); 129 } 130 131 /** 132 * See {@link Record#get(Class, String)}. 133 * 134 * @param name entry name. 135 * @return the value of the entry in this record. 136 */ 137 default Record getRecord(final String name) { 138 return get(Record.class, name); 139 } 140 141 /** 142 * See {@link Record#get(Class, String)}. 143 * 144 * @param type type of the elements of the collection. 145 * @param name entry name. 146 * @param <T> type of the collection elements. 147 * @return the value of the entry in this record. 148 */ 149 default <T> Collection<T> getArray(final Class<T> type, final String name) { 150 return get(Collection.class, name); 151 } 152 153 /** 154 * See {@link Record#get(Class, String)}. 155 * 156 * @param name entry name. 157 * @return the value of the entry in this record. 158 */ 159 default ZonedDateTime getDateTime(final String name) { 160 return get(ZonedDateTime.class, name); 161 } 162 163 /** 164 * See {@link Record#get(Class, String)}. 165 * 166 * @param type type of the elements of the collection. 167 * @param name entry name. 168 * @param <T> type of the collection elements. 169 * @return the value of the entry in this record. 170 */ 171 default <T> Optional<Collection<T>> getOptionalArray(final Class<T> type, final String name) { 172 final Collection<T> value = get(Collection.class, name); 173 return ofNullable(value); 174 } 175 176 /** 177 * See {@link Record#get(Class, String)}. 178 * 179 * @param name entry name. 180 * @return the value of the entry in this record. 181 */ 182 default Optional<ZonedDateTime> getOptionalDateTime(final String name) { 183 return ofNullable(get(ZonedDateTime.class, name)); 184 } 185 186 /** 187 * See {@link Record#get(Class, String)}. 188 * 189 * @param name entry name. 190 * @return the value of the entry in this record. 191 */ 192 default Optional<String> getOptionalString(final String name) { 193 return ofNullable(get(String.class, name)); 194 } 195 196 /** 197 * See {@link Record#get(Class, String)}. 198 * 199 * @param name entry name. 200 * @return the value of the entry in this record. 201 */ 202 default OptionalInt getOptionalInt(final String name) { 203 final Integer value = get(Integer.class, name); 204 return value == null ? OptionalInt.empty() : OptionalInt.of(value); 205 } 206 207 /** 208 * See {@link Record#get(Class, String)}. 209 * 210 * @param name entry name. 211 * @return the value of the entry in this record. 212 */ 213 default OptionalLong getOptionalLong(final String name) { 214 final Long value = get(Long.class, name); 215 return value == null ? OptionalLong.empty() : OptionalLong.of(value); 216 } 217 218 /** 219 * See {@link Record#get(Class, String)}. 220 * 221 * @param name entry name. 222 * @return the value of the entry in this record. 223 */ 224 default OptionalDouble getOptionalDouble(final String name) { 225 final Double value = get(Double.class, name); 226 return value == null ? OptionalDouble.empty() : OptionalDouble.of(value); 227 } 228 229 /** 230 * See {@link Record#get(Class, String)}. 231 * 232 * @param name entry name. 233 * @return the value of the entry in this record. 234 */ 235 default OptionalDouble getOptionalFloat(final String name) { 236 final Float value = get(Float.class, name); 237 return value == null ? OptionalDouble.empty() : OptionalDouble.of(value); 238 } 239 240 /** 241 * See {@link Record#get(Class, String)}. 242 * 243 * @param name entry name. 244 * @return the value of the entry in this record. 245 */ 246 default Optional<Boolean> getOptionalBoolean(final String name) { 247 return ofNullable(get(Boolean.class, name)); 248 } 249 250 /** 251 * See {@link Record#get(Class, String)}. 252 * 253 * @param name entry name. 254 * @return the value of the entry in this record. 255 */ 256 default Optional<byte[]> getOptionalBytes(final String name) { 257 return ofNullable(get(byte[].class, name)); 258 } 259 260 /** 261 * See {@link Record#get(Class, String)}. 262 * 263 * @param name entry name. 264 * @return the value of the entry in this record. 265 */ 266 default Optional<Record> getOptionalRecord(final String name) { 267 return ofNullable(get(Record.class, name)); 268 } 269 270 /** 271 * Allows to create a record with a fluent API. This is the unique recommended way to create a record. 272 */ 273 274 interface Builder { 275 276 Record build(); 277 278 Object getValue(String name); 279 280 List<Entry> getCurrentEntries(); 281 282 /** 283 * Mark that next entry created {@code withXXXX()} will be before {@code entryName} in schema order. 284 * 285 * @see 286 * <ul> 287 * <li>{@link Schema#naturalOrder()}</li> 288 * <li>{@link Schema#getEntriesOrdered()}</li> 289 * <li>{@link Schema#getEntriesOrdered(Comparator)}</li> 290 * </ul> 291 * 292 * @param entryName target entry name. This entry <b>must</b> exist! 293 * 294 * @return this Builder 295 */ 296 default Builder before(String entryName) { 297 throw new UnsupportedOperationException("#before is not implemented"); 298 } 299 300 /** 301 * Mark that next entry created {@code withXXXX()} will be after {@code entryName} in schema order. 302 * 303 * @see 304 * <ul> 305 * <li>{@link Schema#naturalOrder()}</li> 306 * <li>{@link Schema#getEntriesOrdered()}</li> 307 * <li>{@link Schema#getEntriesOrdered(Comparator)}</li> 308 * </ul> 309 * 310 * @param entryName target entry name. This entry <b>must</b> exist! 311 * 312 * @return this Builder 313 */ 314 default Builder after(String entryName) { 315 throw new UnsupportedOperationException("#after"); 316 } 317 318 Builder removeEntry(Schema.Entry schemaEntry); 319 320 Builder updateEntryByName(String name, Schema.Entry schemaEntry); 321 322 Builder with(Schema.Entry entry, Object value); 323 324 Builder withString(String name, String value); 325 326 Builder withString(Schema.Entry entry, String value); 327 328 Builder withBytes(String name, byte[] value); 329 330 Builder withBytes(Schema.Entry entry, byte[] value); 331 332 Builder withDateTime(String name, Date value); 333 334 Builder withDateTime(Schema.Entry entry, Date value); 335 336 Builder withDateTime(String name, ZonedDateTime value); 337 338 Builder withDateTime(Schema.Entry entry, ZonedDateTime value); 339 340 Builder withTimestamp(String name, long value); 341 342 Builder withTimestamp(Schema.Entry entry, long value); 343 344 Builder withInt(String name, int value); 345 346 Builder withInt(Schema.Entry entry, int value); 347 348 Builder withLong(String name, long value); 349 350 Builder withLong(Schema.Entry entry, long value); 351 352 Builder withFloat(String name, float value); 353 354 Builder withFloat(Schema.Entry entry, float value); 355 356 Builder withDouble(String name, double value); 357 358 Builder withDouble(Schema.Entry entry, double value); 359 360 Builder withBoolean(String name, boolean value); 361 362 Builder withBoolean(Schema.Entry entry, boolean value); 363 364 Builder withRecord(Schema.Entry entry, Record value); 365 366 /** 367 * @since 1.1.6 368 * 369 * @param name entry name. 370 * @param value record value. 371 * @return this builder. 372 */ 373 Builder withRecord(String name, Record value); 374 375 <T> Builder withArray(Schema.Entry entry, Collection<T> values); 376 } 377}