This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 5537a3e5 feat(go/adbc/drivermgr): Implement GetObjects for CGO Wrapper
(#1290)
5537a3e5 is described below
commit 5537a3e5da9af02839439818a4c95ad68ce9dfd6
Author: Joel Lubinitsky <[email protected]>
AuthorDate: Tue Nov 14 14:03:38 2023 -0800
feat(go/adbc/drivermgr): Implement GetObjects for CGO Wrapper (#1290)
# What?
Add implementation for `GetObjects` in CGO wrapper for
`adbc_driver_manager`
# Why?
Functionality exists in C++ driver manager but not yet accessible via Go
driver interface.
# Notes
I haven't worked with CGO before so I wanted to limit the scope of this
PR to just one of the unimplemented methods in the wrapper. I would like
to continue implementing the other methods once I know I'm going about
this correctly.
Closes part of #1291
---
go/adbc/drivermgr/wrapper.go | 45 +++++-
go/adbc/drivermgr/wrapper_sqlite_test.go | 236 +++++++++++++++++++++++++++++++
2 files changed, 280 insertions(+), 1 deletion(-)
diff --git a/go/adbc/drivermgr/wrapper.go b/go/adbc/drivermgr/wrapper.go
index cb0d4dc3..1e131e51 100644
--- a/go/adbc/drivermgr/wrapper.go
+++ b/go/adbc/drivermgr/wrapper.go
@@ -208,7 +208,50 @@ func (c *cnxn) GetInfo(_ context.Context, infoCodes
[]adbc.InfoCode) (array.Reco
}
func (c *cnxn) GetObjects(_ context.Context, depth adbc.ObjectDepth, catalog,
dbSchema, tableName, columnName *string, tableType []string)
(array.RecordReader, error) {
- return nil, &adbc.Error{Code: adbc.StatusNotImplemented}
+ var (
+ out C.struct_ArrowArrayStream
+ err C.struct_AdbcError
+ catalog_ *C.char
+ dbSchema_ *C.char
+ tableName_ *C.char
+ columnName_ *C.char
+ tableType_ **C.char
+ )
+
+ if catalog != nil {
+ catalog_ = C.CString(*catalog)
+ defer C.free(unsafe.Pointer(catalog_))
+ }
+
+ if dbSchema != nil {
+ dbSchema_ = C.CString(*dbSchema)
+ defer C.free(unsafe.Pointer(dbSchema_))
+ }
+
+ if tableName != nil {
+ tableName_ = C.CString(*tableName)
+ defer C.free(unsafe.Pointer(tableName_))
+ }
+
+ if columnName != nil {
+ columnName_ = C.CString(*columnName)
+ defer C.free(unsafe.Pointer(columnName_))
+ }
+
+ if len(tableType) > 0 {
+ cArr := []*C.char{}
+ for _, tt := range tableType {
+ cs := C.CString(tt)
+ cArr = append(cArr, cs)
+ defer C.free(unsafe.Pointer(cs))
+ }
+ tableType_ = &cArr[0]
+ }
+
+ if code := adbc.Status(C.AdbcConnectionGetObjects(c.conn, C.int(depth),
catalog_, dbSchema_, tableName_, tableType_, columnName_, &out, &err)); code !=
adbc.StatusOK {
+ return nil, toAdbcError(code, &err)
+ }
+ return getRdr(&out)
}
func (c *cnxn) GetTableSchema(_ context.Context, catalog, dbSchema *string,
tableName string) (*arrow.Schema, error) {
diff --git a/go/adbc/drivermgr/wrapper_sqlite_test.go
b/go/adbc/drivermgr/wrapper_sqlite_test.go
index 2786018d..580b0467 100644
--- a/go/adbc/drivermgr/wrapper_sqlite_test.go
+++ b/go/adbc/drivermgr/wrapper_sqlite_test.go
@@ -52,6 +52,21 @@ func (dm *DriverMgrSuite) SetupSuite() {
"driver": "adbc_driver_sqlite",
})
dm.NoError(err)
+
+ db, err := dm.db.Open(dm.ctx)
+ dm.NoError(err)
+ defer db.Close()
+
+ stmt, err := db.NewStatement()
+ dm.NoError(err)
+ defer stmt.Close()
+
+ err = stmt.SetSqlQuery("CREATE TABLE test_table (id INTEGER PRIMARY
KEY, name TEXT)")
+ dm.NoError(err)
+
+ nrows, err := stmt.ExecuteUpdate(dm.ctx)
+ dm.NoError(err)
+ dm.Equal(int64(0), nrows)
}
func (dm *DriverMgrSuite) SetupTest() {
@@ -98,6 +113,227 @@ func (dm *DriverMgrSuite) TestMetadataGetInfo() {
// TODO(apache/arrow-nanoarrow#76): values are not checked because go
fails to import the union values
}
+func (dm *DriverMgrSuite) TestGetObjects() {
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, nil, nil,
nil, nil, nil)
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(1), rec.NumRows())
+ expRec, _, err := array.RecordFromJSON(
+ memory.DefaultAllocator,
+ expSchema,
+ strings.NewReader(
+ `[
+ {
+ "catalog_name": "main",
+ "catalog_db_schemas": [
+ {
+ "db_schema_tables": [
+ {
+
"table_name": "test_table",
+
"table_type": "table",
+
"table_columns": [
+
{
+
"column_name": "id",
+
"ordinal_position": 1,
+
"xdbc_type_name": "INTEGER",
+
"xdbc_nullable": 1,
+
"xdbc_is_nullable": "YES"
+
},
+
{
+
"column_name": "name",
+
"ordinal_position": 2,
+
"xdbc_type_name": "TEXT",
+
"xdbc_nullable": 1,
+
"xdbc_is_nullable": "YES"
+
}
+ ],
+
"table_constraints": [
+
{
+
"constraint_type": "PRIMARY KEY",
+
"constraint_column_names": ["id"]
+
}
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]`))
+ dm.NoError(err)
+ defer expRec.Release()
+
+ dm.Truef(array.RecordEqual(expRec, rec), "expected: %s\ngot: %s",
expRec, rec)
+ dm.False(rdr.Next())
+}
+
+func (dm *DriverMgrSuite) TestGetObjectsCatalog() {
+ catalog := "does_not_exist"
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, &catalog,
nil, nil, nil, nil)
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(0), rec.NumRows())
+ dm.False(rdr.Next())
+}
+
+func (dm *DriverMgrSuite) TestGetObjectsDBSchema() {
+ dbSchema := "does_not_exist"
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, nil,
&dbSchema, nil, nil, nil)
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(1), rec.NumRows())
+ expRec, _, err := array.RecordFromJSON(
+ memory.DefaultAllocator,
+ expSchema,
+ strings.NewReader(
+ `[
+ {
+ "catalog_name": "main",
+ "catalog_db_schemas": []
+ }
+ ]`))
+ dm.NoError(err)
+ defer expRec.Release()
+
+ dm.Truef(array.RecordEqual(expRec, rec), "expected: %s\ngot: %s",
expRec, rec)
+ dm.False(rdr.Next())
+}
+
+func (dm *DriverMgrSuite) TestGetObjectsTableName() {
+ tableName := "does_not_exist"
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, nil, nil,
&tableName, nil, nil)
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(1), rec.NumRows())
+ expRec, _, err := array.RecordFromJSON(
+ memory.DefaultAllocator,
+ expSchema,
+ strings.NewReader(
+ `[
+ {
+ "catalog_name": "main",
+ "catalog_db_schemas": [
+ {
+ "db_schema_tables": []
+ }
+ ]
+ }
+ ]`))
+ dm.NoError(err)
+ defer expRec.Release()
+
+ dm.Truef(array.RecordEqual(expRec, rec), "expected: %s\ngot: %s",
expRec, rec)
+ dm.False(rdr.Next())
+}
+
+func (dm *DriverMgrSuite) TestGetObjectsColumnName() {
+ columnName := "name"
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, nil, nil,
nil, &columnName, nil)
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(1), rec.NumRows())
+ expRec, _, err := array.RecordFromJSON(
+ memory.DefaultAllocator,
+ expSchema,
+ strings.NewReader(
+ `[
+ {
+ "catalog_name": "main",
+ "catalog_db_schemas": [
+ {
+ "db_schema_tables": [
+ {
+
"table_name": "test_table",
+
"table_type": "table",
+
"table_columns": [
+
{
+
"column_name": "name",
+
"ordinal_position": 2,
+
"xdbc_type_name": "TEXT",
+
"xdbc_nullable": 1,
+
"xdbc_is_nullable": "YES"
+
}
+ ],
+
"table_constraints": [
+
{
+
"constraint_type": "PRIMARY KEY",
+
"constraint_column_names": ["id"]
+
}
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]`))
+ dm.NoError(err)
+ defer expRec.Release()
+
+ dm.Truef(array.RecordEqual(expRec, rec), "expected: %s\ngot: %s",
expRec, rec)
+ dm.False(rdr.Next())
+}
+
+func (dm *DriverMgrSuite) TestGetObjectsTableType() {
+ rdr, err := dm.conn.GetObjects(dm.ctx, adbc.ObjectDepthAll, nil, nil,
nil, nil, []string{"not_a_table"})
+ dm.NoError(err)
+ defer rdr.Release()
+
+ expSchema := adbc.GetObjectsSchema
+ dm.True(expSchema.Equal(rdr.Schema()))
+ dm.True(rdr.Next())
+
+ rec := rdr.Record()
+ dm.Equal(int64(1), rec.NumRows())
+ expRec, _, err := array.RecordFromJSON(
+ memory.DefaultAllocator,
+ expSchema,
+ strings.NewReader(
+ `[
+ {
+ "catalog_name": "main",
+ "catalog_db_schemas": [
+ {
+ "db_schema_tables": []
+ }
+ ]
+ }
+ ]`))
+ dm.NoError(err)
+ defer expRec.Release()
+
+ dm.Truef(array.RecordEqual(expRec, rec), "expected: %s\ngot: %s",
expRec, rec)
+ dm.False(rdr.Next())
+}
+
func (dm *DriverMgrSuite) TestSqlExecute() {
query := "SELECT 1"
st, err := dm.conn.NewStatement()