1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build cdata_integration
// +build cdata_integration
package main
import (
"fmt"
"os"
"runtime"
"unsafe"
"github.com/apache/arrow-go/v18/arrow/array"
"github.com/apache/arrow-go/v18/arrow/cdata"
"github.com/apache/arrow-go/v18/arrow/internal/arrjson"
"github.com/apache/arrow-go/v18/arrow/memory"
"github.com/apache/arrow-go/v18/internal/utils"
)
// #include <stdint.h>
// #include <stdlib.h>
import "C"
var alloc = memory.NewCheckedAllocator(memory.NewGoAllocator())
//export ArrowGo_BytesAllocated
func ArrowGo_BytesAllocated() int64 {
return int64(alloc.CurrentAlloc())
}
//export ArrowGo_RunGC
func ArrowGo_RunGC() {
runtime.GC()
}
//export ArrowGo_FreeError
func ArrowGo_FreeError(cError *C.char) {
C.free(unsafe.Pointer(cError))
}
// When used in a defer() statement, this functions catches an incoming
// panic and converts it into a regular error. This avoids crashing the
// archery integration process and lets other tests proceed.
// Not all panics may be caught and some will still crash the process, though.
func handlePanic(err *error) {
if e := recover(); e != nil {
// Add a prefix while wrapping the panic-error
*err = utils.FormatRecoveredError("panic", e)
}
}
func newJsonReader(cJsonPath *C.char) (*arrjson.Reader, error) {
jsonPath := C.GoString(cJsonPath)
f, err := os.Open(jsonPath)
if err != nil {
return nil, fmt.Errorf("could not open JSON file %q: %w", jsonPath, err)
}
defer f.Close()
jsonReader, err := arrjson.NewReader(f, arrjson.WithAllocator(alloc))
if err != nil {
return nil, fmt.Errorf("could not open JSON file reader from file %q: %w", jsonPath, err)
}
return jsonReader, nil
}
func exportSchemaFromJson(cJsonPath *C.char, out *cdata.CArrowSchema) error {
jsonReader, err := newJsonReader(cJsonPath)
if err != nil {
return err
}
defer jsonReader.Release()
schema := jsonReader.Schema()
defer handlePanic(&err)
cdata.ExportArrowSchema(schema, out)
return err
}
func importSchemaAndCompareToJson(cJsonPath *C.char, cSchema *cdata.CArrowSchema) error {
jsonReader, err := newJsonReader(cJsonPath)
if err != nil {
return err
}
defer jsonReader.Release()
schema := jsonReader.Schema()
importedSchema, err := cdata.ImportCArrowSchema(cSchema)
if err != nil {
return err
}
if !schema.Equal(importedSchema) || !schema.Metadata().Equal(importedSchema.Metadata()) {
return fmt.Errorf(
"Schemas are different:\n- Json Schema: %s\n- Imported Schema: %s",
schema.String(),
importedSchema.String())
}
return nil
}
func exportBatchFromJson(cJsonPath *C.char, num_batch int, out *cdata.CArrowArray) error {
// XXX this function exports a single batch at a time, but the JSON reader
// reads all batches at construction.
jsonReader, err := newJsonReader(cJsonPath)
if err != nil {
return err
}
defer jsonReader.Release()
batch, err := jsonReader.ReadAt(num_batch)
if err != nil {
return err
}
defer handlePanic(&err)
cdata.ExportArrowRecordBatch(batch, out, nil)
return err
}
func importBatchAndCompareToJson(cJsonPath *C.char, num_batch int, cArray *cdata.CArrowArray) error {
jsonReader, err := newJsonReader(cJsonPath)
if err != nil {
return err
}
defer jsonReader.Release()
schema := jsonReader.Schema()
batch, err := jsonReader.ReadAt(num_batch)
if err != nil {
return err
}
importedBatch, err := cdata.ImportCRecordBatchWithSchema(cArray, schema)
if err != nil {
return err
}
defer importedBatch.Release()
if !array.RecordEqual(batch, importedBatch) {
return fmt.Errorf(
"Batches are different:\n- Json Batch: %v\n- Imported Batch: %v",
batch, importedBatch)
}
return nil
}
//export ArrowGo_ExportSchemaFromJson
func ArrowGo_ExportSchemaFromJson(cJsonPath *C.char, out uintptr) *C.char {
err := exportSchemaFromJson(cJsonPath, cdata.SchemaFromPtr(out))
if err != nil {
return C.CString(err.Error())
}
return nil
}
//export ArrowGo_ExportBatchFromJson
func ArrowGo_ExportBatchFromJson(cJsonPath *C.char, num_batch int, out uintptr) *C.char {
err := exportBatchFromJson(cJsonPath, num_batch, cdata.ArrayFromPtr(out))
if err != nil {
return C.CString(err.Error())
}
return nil
}
//export ArrowGo_ImportSchemaAndCompareToJson
func ArrowGo_ImportSchemaAndCompareToJson(cJsonPath *C.char, cSchema uintptr) *C.char {
err := importSchemaAndCompareToJson(cJsonPath, cdata.SchemaFromPtr(cSchema))
if err != nil {
return C.CString(err.Error())
}
return nil
}
//export ArrowGo_ImportBatchAndCompareToJson
func ArrowGo_ImportBatchAndCompareToJson(cJsonPath *C.char, num_batch int, cArray uintptr) *C.char {
err := importBatchAndCompareToJson(cJsonPath, num_batch, cdata.ArrayFromPtr(cArray))
if err != nil {
return C.CString(err.Error())
}
return nil
}
func main() {}
|