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