001/*
002 * Copyright 2015-2022 Transmogrify LLC, 2022-2026 Revetware LLC.
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 */
016
017package com.pyranid;
018
019import org.jspecify.annotations.NonNull;
020
021import javax.annotation.concurrent.ThreadSafe;
022import java.util.List;
023import java.util.Optional;
024
025/**
026 * Encapsulates {@link java.sql.PreparedStatement} parameter data meant to be bound to a formal
027 * {@link java.sql.Struct} by {@link PreparedStatementBinder}.
028 * <p>
029 * The type name is database-specific and is passed to
030 * {@link java.sql.Connection#createStruct(String, Object[])}. For example, DuckDB accepts an inline
031 * type such as {@code STRUCT(name VARCHAR, age INTEGER)}. Attributes are positional and may contain
032 * {@code null}, nested {@code SqlStructParameter}s, or {@link SqlArrayParameter}s.
033 * <p>
034 * DuckDB attributes that represent an instant require a complete inline STRUCT declaration so Pyranid
035 * can distinguish {@code TIMESTAMP} from {@code TIMESTAMPTZ}. A named {@code CREATE TYPE} alias does not
036 * expose its attribute types through this binding path, so binding an instant-bearing value through one
037 * fails fast rather than guessing its timestamp semantics.
038 * <p>
039 * Standard instances may be constructed via {@link Parameters#sqlStructOf(String, Object[])} and
040 * {@link Parameters#sqlStructOf(String, List)}.
041 * <p>
042 * Implementations should be threadsafe.
043 *
044 * @author <a href="https://www.revetkn.com">Mark Allen</a>
045 * @since 4.7.0
046 */
047@ThreadSafe
048public interface SqlStructParameter {
049        /**
050         * Gets the database-specific SQL STRUCT type name.
051         *
052         * @return the SQL STRUCT type name
053         */
054        @NonNull
055        String getTypeName();
056
057        /**
058         * Gets the positional attributes of this SQL STRUCT.
059         *
060         * @return the attributes, or {@link Optional#empty()} when the SQL STRUCT itself is {@code NULL}
061         */
062        @NonNull
063        Optional<Object[]> getAttributes();
064}