16#ifndef QGSARROWITERATOR_H
17#define QGSARROWITERATOR_H
24#ifndef ARROW_C_DATA_INTERFACE
25#define ARROW_C_DATA_INTERFACE
27#define ARROW_FLAG_DICTIONARY_ORDERED 1
28#define ARROW_FLAG_NULLABLE 2
29#define ARROW_FLAG_MAP_KEYS_SORTED 4
41 struct ArrowSchema **children;
42 struct ArrowSchema *dictionary;
45 void ( *release )(
struct ArrowSchema * );
63 struct ArrowArray **children;
64 struct ArrowArray *dictionary;
67 void ( *release )(
struct ArrowArray * );
76#ifndef ARROW_C_STREAM_INTERFACE
77#define ARROW_C_STREAM_INTERFACE
81struct ArrowArrayStream
84 int ( *get_schema )(
struct ArrowArrayStream *,
struct ArrowSchema *out );
85 int ( *get_next )(
struct ArrowArrayStream *,
struct ArrowArray *out );
86 const char *( *get_last_error )(
struct ArrowArrayStream * );
89 void ( *release )(
struct ArrowArrayStream * );
127 QString mGeometryColumnName;
160 struct ArrowSchema *
schema();
163 const struct ArrowSchema *
schema()
const;
205 SIP_PYOBJECT __arrow_c_schema__();
207 struct ArrowSchema *exportedSchema =
static_cast<struct ArrowSchema *
>( malloc(
sizeof(
struct ArrowSchema ) ) );
208 if ( !exportedSchema )
210 PyErr_SetString( PyExc_MemoryError,
"Failed to allocate ArrowSchema" );
215 memcpy( exportedSchema, sipCpp->schema(),
sizeof(
struct ArrowSchema ) );
216 sipCpp->schema()->release =
nullptr;
217 sipRes = PyCapsule_New( exportedSchema,
"arrow_schema", []( PyObject *capsule )
219 struct ArrowSchema *
schema =
static_cast<struct ArrowSchema *
>( PyCapsule_GetPointer( capsule,
"arrow_schema" ) );
228 if ( exportedSchema->release )
230 exportedSchema->release( exportedSchema );
232 free( exportedSchema );
249 if ( PyCapsule_CheckExact( a0 ) && PyCapsule_IsValid( a0,
"arrow_schema" ) ) {
250 struct ArrowSchema *capsuleSchema =
static_cast<struct ArrowSchema *
>( PyCapsule_GetPointer( a0,
"arrow_schema" ) );
252 memcpy(newSchema->
schema(), capsuleSchema,
sizeof(
struct ArrowSchema));
253 capsuleSchema->release =
nullptr;
254 sipRes = sipConvertFromNewType( newSchema, sipType_QgsArrowSchema,
nullptr );
256 else if ( PyObject_HasAttrString( a0,
"__arrow_c_schema__" ) )
258 PyObject *method = PyObject_GetAttrString( a0,
"__arrow_c_schema__" );
261 PyObject *capsule = PyObject_CallObject( method,
nullptr );
265 if ( PyCapsule_CheckExact( capsule ) && PyCapsule_IsValid( capsule,
"arrow_schema" ) )
267 struct ArrowSchema *capsuleSchema =
static_cast<struct ArrowSchema *
>( PyCapsule_GetPointer( capsule,
"arrow_schema" ) );
269 memcpy(newSchema->
schema(), capsuleSchema,
sizeof(
struct ArrowSchema));
270 capsuleSchema->release =
nullptr;
271 sipRes = sipConvertFromNewType( newSchema, sipType_QgsArrowSchema,
nullptr );
275 PyErr_SetString( PyExc_TypeError,
"__arrow_c_schema__() did not return a valid arrow_schema PyCapsule" );
278 Py_DECREF( capsule );
292 PyErr_Format( PyExc_TypeError,
"Expected an object implementing __arrow_c_schema__(), got %s", Py_TYPE( a0 )->tp_name );
299 struct ArrowSchema mSchema {};
300 int mGeometryColumnIndex = -1;
337 struct ArrowArray *
array();
340 const struct ArrowArray *
array()
const;
361 struct ArrowArray mArray {};
433 SIP_PYOBJECT __arrow_c_stream__( SIP_PYOBJECT requested_schema = Py_None );
436 struct ArrowArrayStream *exportedStream =
static_cast<struct ArrowArrayStream *
>( malloc(
sizeof(
struct ArrowArrayStream ) ) );
437 if ( !exportedStream )
439 PyErr_SetString( PyExc_MemoryError,
"Failed to allocate ArrowArrayStream" );
444 memcpy( exportedStream, sipCpp->arrayStream(),
sizeof(
struct ArrowArrayStream ) );
445 sipCpp->arrayStream()->release =
nullptr;
446 sipRes = PyCapsule_New( exportedStream,
"arrow_array_stream", []( PyObject *capsule )
448 struct ArrowArrayStream *stream =
static_cast<struct ArrowArrayStream *
>( PyCapsule_GetPointer( capsule,
"arrow_array_stream" ) );
449 if ( stream && stream->release )
451 stream->release( stream );
457 if ( exportedStream->release )
459 exportedStream->release( exportedStream );
461 free( exportedStream );
476 static SIP_PYOBJECT fromArrow( SIP_PYOBJECT obj )
SIP_TYPEHINT( QgsArrowArrayStream );
478 if ( PyCapsule_CheckExact( a0 ) && PyCapsule_IsValid( a0,
"arrow_array_stream" ) )
480 struct ArrowArrayStream *capsuleStream =
static_cast<struct ArrowArrayStream *
>( PyCapsule_GetPointer( a0,
"arrow_array_stream" ) );
481 QgsArrowArrayStream *newStream =
new QgsArrowArrayStream();
482 memcpy(newStream->
arrayStream(), capsuleStream,
sizeof(
struct ArrowArrayStream));
483 capsuleStream->release =
nullptr;
484 sipRes = sipConvertFromNewType( newStream, sipType_QgsArrowArrayStream,
nullptr );
486 else if ( PyObject_HasAttrString( a0,
"__arrow_c_stream__" ) )
488 PyObject *method = PyObject_GetAttrString( a0,
"__arrow_c_stream__" );
491 PyObject *capsule = PyObject_CallObject( method,
nullptr );
495 if ( PyCapsule_CheckExact( capsule ) && PyCapsule_IsValid( capsule,
"arrow_array_stream" ) )
497 struct ArrowArrayStream *capsuleStream =
static_cast<struct ArrowArrayStream *
>( PyCapsule_GetPointer( capsule,
"arrow_array_stream" ) );
498 QgsArrowArrayStream *newStream =
new QgsArrowArrayStream();
499 memcpy(newStream->
arrayStream(), capsuleStream,
sizeof(
struct ArrowArrayStream));
500 capsuleStream->release =
nullptr;
501 sipRes = sipConvertFromNewType( newStream, sipType_QgsArrowArrayStream,
nullptr );
505 PyErr_SetString( PyExc_TypeError,
"__arrow_c_stream__() did not return a valid arrow_array_stream PyCapsule" );
508 Py_DECREF( capsule );
522 PyErr_Format( PyExc_TypeError,
"Expected an object implementing __arrow_c_stream__(), got %s", Py_TYPE( a0 )->tp_name );
529 struct ArrowArrayStream mArrayStream {};
532 QgsArrowArrayStream(
const QgsArrowArrayStream &other );
554 struct ArrowSchema *
schema();
Wrapper around an ArrowArrayStream.
QgsArrowArrayStream & operator=(QgsArrowArrayStream &other)=delete
struct ArrowArrayStream * arrayStream()
Access the underlying ArrowArray from C++.
unsigned long long cArrayStreamAddress() const
Returns the address of the underlying ArrowArrayStream for import or export across boundaries.
QgsArrowArrayStream()=default
Construct invalid array stream holder.
void exportToAddress(unsigned long long otherAddress)
Export this array to the address of an empty ArrowArrayStream for export across boundaries.
bool isValid() const
Returns true if this wrapper object holds a valid ArrowArray.
QgsArrowArrayStream(const QgsArrowArrayStream &other)=delete
Wrapper around an ArrowArray.
QgsArrowArray()=default
Construct invalid array holder.
struct ArrowArray * array()
Access the underlying ArrowArray from C++.
QgsArrowArray & operator=(QgsArrowArray &other)=delete
bool isValid() const
Returns true if this wrapper object holds a valid ArrowArray.
QgsArrowArray(const QgsArrowArray &other)=delete
void exportToAddress(unsigned long long otherAddress)
Export this array to the address of an empty ArrowArray for export across boundaries.
unsigned long long cArrayAddress() const
Returns the address of the underlying ArrowArray for import or export across boundaries.
Options for inferring an ArrowSchema from a feature source.
void setGeometryColumnName(const QString &geometryColumnName)
Set the name that should be used to refer to the geometry column.
QgsArrowInferSchemaOptions()
Construct default options.
QString geometryColumnName() const
The name that should be used for a layer's geometry column.
static QgsArrowSchema inferSchema(const QgsVectorLayer &layer, const QgsArrowInferSchemaOptions &options=QgsArrowInferSchemaOptions())
Infer the QgsArrowSchema for a given QgsVectorLayer.
struct ArrowSchema * schema()
Access the output ArrowSchema from C++.
QgsArrowArrayStream toArrayStream(int batchSize=65536) const
Export this iterator as an ArrowArrayStream.
QgsArrowArray nextFeatures(int n)
Build an ArrowArray using the next n features (or fewer depending on the number of features remaining...
QgsArrowIterator()=default
Construct invalid iterator.
void setSchema(const QgsArrowSchema &schema)
Set the ArrowSchema for the output of all future batches.
Wrapper around an ArrowSchema.
int geometryColumnIndex() const
Returns the index of the column in this schema that should be populated with a feature geometry.
bool isValid() const
Returns true if this wrapper object holds a valid ArrowSchema.
unsigned long long cSchemaAddress() const
Returns the address of the underlying ArrowSchema for import or export across boundaries.
struct ArrowSchema * schema()
Access the underlying ArrowSchema from C++.
QgsArrowSchema & operator=(const QgsArrowSchema &other)
Assignment operator.
void exportToAddress(unsigned long long otherAddress)
Export this array to the address of an empty ArrowSchema for export across boundaries.
QgsArrowSchema()
Construct invalid schema holder.
void setGeometryColumnIndex(int geometryColumnIndex)
Set the index of the column in this schema that should be populated with a feature geometry.
Represents a coordinate reference system (CRS).
Defines a QGIS exception class.
Wrapper for iterator of features from vector data provider or vector layer.
Container of fields for a vector layer.
Represents a vector layer which manages a vector based dataset.
#define SIP_TYPEHINT(type)
#define SIP_THROW(name,...)