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