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.Date;
023import java.util.List;
024import java.util.Optional;
025import java.util.OptionalDouble;
026import java.util.OptionalInt;
027import java.util.OptionalLong;
028
029import org.talend.sdk.component.api.record.Schema.Entry;
030
031public interface Record {
032
033    /**
034     * @return the schema of this record.
035     */
036    Schema getSchema();
037
038    /**
039     * Create a Builder with values of the record present in {@link Schema}.
040     * 
041     * @param schema new schema
042     * @return a {@link Record.Builder}
043     */
044    default Builder withNewSchema(Schema schema) {
045        throw new UnsupportedOperationException("#withNewSchema is not implemented");
046    }
047
048    /**
049     * Access a record field value.
050     *
051     * IMPORTANT: it is always better to use the typed accessors and the optional flavor when the entry is nullable.
052     *
053     * @param expectedType the expected type for the column.
054     * @param name the name of the column.
055     * @param <T> the type of expectedType.
056     * @return the column value.
057     */
058    <T> T get(Class<T> expectedType, String name);
059
060    /**
061     * See {@link Record#get(Class, String)}.
062     * 
063     * @param name entry name.
064     * @return the value of the entry in this record.
065     */
066    default String getString(final String name) {
067        return get(String.class, name);
068    }
069
070    /**
071     * See {@link Record#get(Class, String)}.
072     * 
073     * @param name entry name.
074     * @return the value of the entry in this record.
075     */
076    default int getInt(final String name) {
077        return get(Integer.class, name);
078    }
079
080    /**
081     * See {@link Record#get(Class, String)}.
082     * 
083     * @param name entry name.
084     * @return the value of the entry in this record.
085     */
086    default long getLong(final String name) {
087        return get(Long.class, name);
088    }
089
090    /**
091     * See {@link Record#get(Class, String)}.
092     * 
093     * @param name entry name.
094     * @return the value of the entry in this record.
095     */
096    default double getDouble(final String name) {
097        return get(Double.class, name);
098    }
099
100    /**
101     * See {@link Record#get(Class, String)}.
102     * 
103     * @param name entry name.
104     * @return the value of the entry in this record.
105     */
106    default float getFloat(final String name) {
107        return get(Float.class, name);
108    }
109
110    /**
111     * See {@link Record#get(Class, String)}.
112     * 
113     * @param name entry name.
114     * @return the value of the entry in this record.
115     */
116    default boolean getBoolean(final String name) {
117        return get(Boolean.class, name);
118    }
119
120    /**
121     * See {@link Record#get(Class, String)}.
122     * 
123     * @param name entry name.
124     * @return the value of the entry in this record.
125     */
126    default byte[] getBytes(final String name) {
127        return get(byte[].class, name);
128    }
129
130    /**
131     * See {@link Record#get(Class, String)}.
132     * 
133     * @param name entry name.
134     * @return the value of the entry in this record.
135     */
136    default Record getRecord(final String name) {
137        return get(Record.class, name);
138    }
139
140    /**
141     * See {@link Record#get(Class, String)}.
142     * 
143     * @param type type of the elements of the collection.
144     * @param name entry name.
145     * @param <T> type of the collection elements.
146     * @return the value of the entry in this record.
147     */
148    default <T> Collection<T> getArray(final Class<T> type, final String name) {
149        return get(Collection.class, name);
150    }
151
152    /**
153     * See {@link Record#get(Class, String)}.
154     * 
155     * @param name entry name.
156     * @return the value of the entry in this record.
157     */
158    default ZonedDateTime getDateTime(final String name) {
159        return get(ZonedDateTime.class, name);
160    }
161
162    /**
163     * See {@link Record#get(Class, String)}.
164     * 
165     * @param type type of the elements of the collection.
166     * @param name entry name.
167     * @param <T> type of the collection elements.
168     * @return the value of the entry in this record.
169     */
170    default <T> Optional<Collection<T>> getOptionalArray(final Class<T> type, final String name) {
171        final Collection<T> value = get(Collection.class, name);
172        return ofNullable(value);
173    }
174
175    /**
176     * See {@link Record#get(Class, String)}.
177     * 
178     * @param name entry name.
179     * @return the value of the entry in this record.
180     */
181    default Optional<ZonedDateTime> getOptionalDateTime(final String name) {
182        return ofNullable(get(ZonedDateTime.class, name));
183    }
184
185    /**
186     * See {@link Record#get(Class, String)}.
187     * 
188     * @param name entry name.
189     * @return the value of the entry in this record.
190     */
191    default Optional<String> getOptionalString(final String name) {
192        return ofNullable(get(String.class, name));
193    }
194
195    /**
196     * See {@link Record#get(Class, String)}.
197     * 
198     * @param name entry name.
199     * @return the value of the entry in this record.
200     */
201    default OptionalInt getOptionalInt(final String name) {
202        final Integer value = get(Integer.class, name);
203        return value == null ? OptionalInt.empty() : OptionalInt.of(value);
204    }
205
206    /**
207     * See {@link Record#get(Class, String)}.
208     * 
209     * @param name entry name.
210     * @return the value of the entry in this record.
211     */
212    default OptionalLong getOptionalLong(final String name) {
213        final Long value = get(Long.class, name);
214        return value == null ? OptionalLong.empty() : OptionalLong.of(value);
215    }
216
217    /**
218     * See {@link Record#get(Class, String)}.
219     * 
220     * @param name entry name.
221     * @return the value of the entry in this record.
222     */
223    default OptionalDouble getOptionalDouble(final String name) {
224        final Double value = get(Double.class, name);
225        return value == null ? OptionalDouble.empty() : OptionalDouble.of(value);
226    }
227
228    /**
229     * See {@link Record#get(Class, String)}.
230     * 
231     * @param name entry name.
232     * @return the value of the entry in this record.
233     */
234    default OptionalDouble getOptionalFloat(final String name) {
235        final Float value = get(Float.class, name);
236        return value == null ? OptionalDouble.empty() : OptionalDouble.of(value);
237    }
238
239    /**
240     * See {@link Record#get(Class, String)}.
241     * 
242     * @param name entry name.
243     * @return the value of the entry in this record.
244     */
245    default Optional<Boolean> getOptionalBoolean(final String name) {
246        return ofNullable(get(Boolean.class, name));
247    }
248
249    /**
250     * See {@link Record#get(Class, String)}.
251     * 
252     * @param name entry name.
253     * @return the value of the entry in this record.
254     */
255    default Optional<byte[]> getOptionalBytes(final String name) {
256        return ofNullable(get(byte[].class, name));
257    }
258
259    /**
260     * See {@link Record#get(Class, String)}.
261     * 
262     * @param name entry name.
263     * @return the value of the entry in this record.
264     */
265    default Optional<Record> getOptionalRecord(final String name) {
266        return ofNullable(get(Record.class, name));
267    }
268
269    /**
270     * Allows to create a record with a fluent API. This is the unique recommended way to create a record.
271     */
272    interface Builder {
273
274        Record build();
275
276        Object getValue(String name);
277
278        List<Entry> getCurrentEntries();
279
280        Builder removeEntry(Schema.Entry schemaEntry);
281
282        Builder updateEntryByName(String name, Schema.Entry schemaEntry);
283
284        Builder with(Schema.Entry entry, Object value);
285
286        Builder withString(String name, String value);
287
288        Builder withString(Schema.Entry entry, String value);
289
290        Builder withBytes(String name, byte[] value);
291
292        Builder withBytes(Schema.Entry entry, byte[] value);
293
294        Builder withDateTime(String name, Date value);
295
296        Builder withDateTime(Schema.Entry entry, Date value);
297
298        Builder withDateTime(String name, ZonedDateTime value);
299
300        Builder withDateTime(Schema.Entry entry, ZonedDateTime value);
301
302        Builder withTimestamp(String name, long value);
303
304        Builder withTimestamp(Schema.Entry entry, long value);
305
306        Builder withInt(String name, int value);
307
308        Builder withInt(Schema.Entry entry, int value);
309
310        Builder withLong(String name, long value);
311
312        Builder withLong(Schema.Entry entry, long value);
313
314        Builder withFloat(String name, float value);
315
316        Builder withFloat(Schema.Entry entry, float value);
317
318        Builder withDouble(String name, double value);
319
320        Builder withDouble(Schema.Entry entry, double value);
321
322        Builder withBoolean(String name, boolean value);
323
324        Builder withBoolean(Schema.Entry entry, boolean value);
325
326        Builder withRecord(Schema.Entry entry, Record value);
327
328        /**
329         * @since 1.1.6
330         *
331         * @param name entry name.
332         * @param value record value.
333         * @return this builder.
334         */
335        Builder withRecord(String name, Record value);
336
337        <T> Builder withArray(Schema.Entry entry, Collection<T> values);
338    }
339}