001/**
002 * Copyright (C) 2006-2021 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     * Access a record field value.
040     *
041     * IMPORTANT: it is always better to use the typed accessors and the optional flavor when the entry is nullable.
042     *
043     * @param expectedType the expected type for the column.
044     * @param name the name of the column.
045     * @param <T> the type of expectedType.
046     * @return the column value.
047     */
048    <T> T get(Class<T> expectedType, String name);
049
050    /**
051     * See {@link Record#get(Class, String)}.
052     * 
053     * @param name entry name.
054     * @return the value of the entry in this record.
055     */
056    default String getString(final String name) {
057        return get(String.class, name);
058    }
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 int getInt(final String name) {
067        return get(Integer.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 long getLong(final String name) {
077        return get(Long.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 double getDouble(final String name) {
087        return get(Double.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 float getFloat(final String name) {
097        return get(Float.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 boolean getBoolean(final String name) {
107        return get(Boolean.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 byte[] getBytes(final String name) {
117        return get(byte[].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 Record getRecord(final String name) {
127        return get(Record.class, name);
128    }
129
130    /**
131     * See {@link Record#get(Class, String)}.
132     * 
133     * @param type type of the elements of the collection.
134     * @param name entry name.
135     * @param <T> type of the collection elements.
136     * @return the value of the entry in this record.
137     */
138    default <T> Collection<T> getArray(final Class<T> type, final String name) {
139        return get(Collection.class, name);
140    }
141
142    /**
143     * See {@link Record#get(Class, String)}.
144     * 
145     * @param name entry name.
146     * @return the value of the entry in this record.
147     */
148    default ZonedDateTime getDateTime(final String name) {
149        return get(ZonedDateTime.class, name);
150    }
151
152    /**
153     * See {@link Record#get(Class, String)}.
154     * 
155     * @param type type of the elements of the collection.
156     * @param name entry name.
157     * @param <T> type of the collection elements.
158     * @return the value of the entry in this record.
159     */
160    default <T> Optional<Collection<T>> getOptionalArray(final Class<T> type, final String name) {
161        final Collection<T> value = get(Collection.class, name);
162        return ofNullable(value);
163    }
164
165    /**
166     * See {@link Record#get(Class, String)}.
167     * 
168     * @param name entry name.
169     * @return the value of the entry in this record.
170     */
171    default Optional<ZonedDateTime> getOptionalDateTime(final String name) {
172        return ofNullable(get(ZonedDateTime.class, name));
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<String> getOptionalString(final String name) {
182        return ofNullable(get(String.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 OptionalInt getOptionalInt(final String name) {
192        final Integer value = get(Integer.class, name);
193        return value == null ? OptionalInt.empty() : OptionalInt.of(value);
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 OptionalLong getOptionalLong(final String name) {
203        final Long value = get(Long.class, name);
204        return value == null ? OptionalLong.empty() : OptionalLong.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 OptionalDouble getOptionalDouble(final String name) {
214        final Double value = get(Double.class, name);
215        return value == null ? OptionalDouble.empty() : OptionalDouble.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 getOptionalFloat(final String name) {
225        final Float value = get(Float.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 Optional<Boolean> getOptionalBoolean(final String name) {
236        return ofNullable(get(Boolean.class, name));
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<byte[]> getOptionalBytes(final String name) {
246        return ofNullable(get(byte[].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<Record> getOptionalRecord(final String name) {
256        return ofNullable(get(Record.class, name));
257    }
258
259    /**
260     * Allows to create a record with a fluent API. This is the unique recommended way to create a record.
261     */
262    interface Builder {
263
264        Record build();
265
266        Object getValue(String name);
267
268        List<Entry> getCurrentEntries();
269
270        Builder removeEntry(Schema.Entry schemaEntry);
271
272        Builder updateEntryByName(String name, Schema.Entry schemaEntry);
273
274        Builder with(Schema.Entry entry, Object value);
275
276        Builder withString(String name, String value);
277
278        Builder withString(Schema.Entry entry, String value);
279
280        Builder withBytes(String name, byte[] value);
281
282        Builder withBytes(Schema.Entry entry, byte[] value);
283
284        Builder withDateTime(String name, Date value);
285
286        Builder withDateTime(Schema.Entry entry, Date value);
287
288        Builder withDateTime(String name, ZonedDateTime value);
289
290        Builder withDateTime(Schema.Entry entry, ZonedDateTime value);
291
292        Builder withTimestamp(String name, long value);
293
294        Builder withTimestamp(Schema.Entry entry, long value);
295
296        Builder withInt(String name, int value);
297
298        Builder withInt(Schema.Entry entry, int value);
299
300        Builder withLong(String name, long value);
301
302        Builder withLong(Schema.Entry entry, long value);
303
304        Builder withFloat(String name, float value);
305
306        Builder withFloat(Schema.Entry entry, float value);
307
308        Builder withDouble(String name, double value);
309
310        Builder withDouble(Schema.Entry entry, double value);
311
312        Builder withBoolean(String name, boolean value);
313
314        Builder withBoolean(Schema.Entry entry, boolean value);
315
316        Builder withRecord(Schema.Entry entry, Record value);
317
318        /**
319         * @since 1.1.6
320         *
321         * @param name entry name.
322         * @param value record value.
323         * @return this builder.
324         */
325        Builder withRecord(String name, Record value);
326
327        <T> Builder withArray(Schema.Entry entry, Collection<T> values);
328    }
329}