Skip to content

Commit 6be5c4b

Browse files
committed
feat: add support for the new rowset type ROWSET_TYPE_METADATA_v1
1 parent 147df91 commit 6be5c4b

6 files changed

Lines changed: 201 additions & 53 deletions

File tree

cli/sqlc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// //// SQLite Cloud
33
// //////////// ///
44
// /// /// /// Product : SQLite Cloud CLI Application
5-
// /// /// /// Version : 1.1.1
5+
// /// /// /// Version : 1.1.0
66
// // /// /// /// Date : 2021/10/08
77
// /// /// /// /// Author : Andreas Pfeil
88
// /// /// /// ///
@@ -37,7 +37,7 @@ import (
3737

3838
var app_name = "sqlc"
3939
var long_name = "SQLite Cloud Command Line Application"
40-
var version = "version 1.0.0"
40+
var version = "version 1.1.0"
4141
var copyright = "(c) 2021 by SQLite Cloud Inc."
4242
var history_file = fmt.Sprintf("~/.%s_history.txt", app_name)
4343

connection.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ func (this *SQCloud) Execute(SQL string) error {
616616
if result, err := this.Select(SQL); result != nil {
617617
defer result.Free()
618618

619-
if !result.IsOK() {
619+
if !result.IsOK() && !result.IsArray() {
620620
return errors.New("ERROR: Unexpected Result (-1)")
621621
}
622622
return err
@@ -629,7 +629,7 @@ func (this *SQCloud) ExecuteArray(SQL string, values []interface{}) error {
629629
if result, err := this.SelectArray(SQL, values); result != nil {
630630
defer result.Free()
631631

632-
if !result.IsOK() {
632+
if !result.IsOK() && !result.IsArray() {
633633
return errors.New("ERROR: Unexpected Result (-1)")
634634
}
635635
return err

result.go

Lines changed: 163 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,35 @@ const OUTFORMAT_TABLE = 8
4545
const OUTFORMAT_BOX = 9
4646
const OUTFORMAT_XML = 10
4747

48+
const ROWSET_TYPE_BASIC = 1
49+
const ROWSET_TYPE_METADATA_v1 = 2
50+
const ROWSET_TYPE_HEADER_ONLY = 3
51+
const ROWSET_TYPE_DATA_ONLY = 4
52+
4853
// The Result is either a Literal or a RowSet
4954
type Result struct {
5055
uncompressedChuckSizeSum uint64
5156

5257
value Value
58+
rows []ResultRow
59+
60+
// columns metadata
61+
Name []string
62+
Width []uint64
63+
DeclType []string
64+
DbName []string
65+
TblName []string
66+
OrigName []string
67+
Notnull []int32
68+
PriKey []int32
69+
Autoinc []int32
5370

54-
rows []ResultRow
55-
ColumnNames []string
56-
ColumnWidth []uint64
5771
MaxHeaderWidth uint64
5872
}
5973

6074
var OKResult = Result{
6175
value: Value{Type: '+', Buffer: []byte("OK")}, // This is an unset Value
6276
rows: nil,
63-
ColumnNames: nil,
64-
ColumnWidth: nil,
6577
MaxHeaderWidth: 0,
6678
uncompressedChuckSizeSum: 0,
6779
}
@@ -92,7 +104,7 @@ func (this *Result) GetNumberOfColumns() uint64 {
92104
case !this.IsRowSet():
93105
return 0
94106
default:
95-
return uint64(len(this.ColumnWidth))
107+
return uint64(len(this.Width))
96108
}
97109
}
98110

@@ -124,7 +136,7 @@ func (this *Result) GetMaxColumnWidth(Column uint64) (uint64, error) {
124136
case Column >= this.GetNumberOfColumns():
125137
return 0, errors.New("Column Index out of bounds")
126138
default:
127-
return this.ColumnWidth[Column], nil
139+
return this.Width[Column], nil
128140
}
129141
}
130142

@@ -137,7 +149,7 @@ func (this *Result) GetNameLength(Column uint64) (uint64, error) {
137149
case Column >= this.GetNumberOfColumns():
138150
return 0, errors.New("Column Index out of bounds")
139151
default:
140-
return uint64(len(this.ColumnNames[Column])), nil
152+
return uint64(len(this.Name[Column])), nil
141153
}
142154
}
143155

@@ -187,9 +199,9 @@ func (this *Result) IsRowSet() bool {
187199
return false
188200
case this.rows == nil:
189201
return false
190-
case this.ColumnNames == nil:
202+
case this.Name == nil:
191203
return false
192-
case this.ColumnWidth == nil:
204+
case this.Width == nil:
193205
return false
194206
case this.MaxHeaderWidth == 0:
195207
return false
@@ -328,8 +340,16 @@ func (this *Result) GetErrorAsString() string {
328340
func (this *Result) Free() {
329341
this.value = Value{Type: 0, Buffer: nil} // GC
330342
this.rows = []ResultRow{} // GC
331-
this.ColumnNames = []string{} // GC
332-
this.ColumnWidth = []uint64{} // GC
343+
this.Name = []string{} // GC
344+
this.Width = []uint64{} // GC
345+
this.DeclType = []string{} // GC
346+
this.DbName = []string{}
347+
this.TblName = []string{}
348+
this.OrigName = []string{}
349+
this.Notnull = []int32{}
350+
this.PriKey = []int32{}
351+
this.Autoinc = []int32{}
352+
333353
this.MaxHeaderWidth = 0
334354
}
335355

@@ -340,7 +360,7 @@ func (this *Result) GetName(Column uint64) (string, error) {
340360
case Column >= this.GetNumberOfColumns():
341361
return "", errors.New("Column Index out of bounds")
342362
default:
343-
return this.ColumnNames[Column], nil
363+
return this.Name[Column], nil
344364
}
345365
}
346366
func (this *Result) GetName_(Column uint64) string {
@@ -520,14 +540,14 @@ func renderCenteredString(Buffer string, Width int) string {
520540

521541
func (this *Result) renderHorizontalTableLine(Left string, Fill string, Separator string, Right string) string {
522542
outBuffer := ""
523-
for _, columnWidth := range this.ColumnWidth {
543+
for _, columnWidth := range this.Width {
524544
outBuffer = fmt.Sprintf("%s%s%s", outBuffer, strings.Repeat(Fill, int(columnWidth+2)), Separator)
525545
}
526546
return fmt.Sprintf("%s%s%s", Left, strings.TrimRight(outBuffer, Separator), Right)
527547
}
528548
func (this *Result) renderTableColumnNames(Left string, Separator string, Right string) string {
529549
outBuffer := ""
530-
for forThisColumn, columnWidth := range this.ColumnWidth {
550+
for forThisColumn, columnWidth := range this.Width {
531551
columnName, _ := this.GetName(uint64(forThisColumn))
532552
outBuffer = fmt.Sprintf("%s%s%s", outBuffer, renderCenteredString(columnName, int(columnWidth+2)), Separator)
533553
}
@@ -713,14 +733,14 @@ func GetDefaultSeparatorForOutputFormat(Format int) (string, error) {
713733
}
714734
}
715735

716-
//////
736+
// ////
717737
// is called from connection.Select
718738
func (this *SQCloud) readResult() (*Result, error) {
719739
ErrorResult := Result{
720740
value: Value{Type: '-', Buffer: []byte("100000 Unknown internal error")}, // This is an unset Value
721741
rows: nil,
722-
ColumnNames: nil,
723-
ColumnWidth: nil,
742+
Name: nil,
743+
Width: nil,
724744
MaxHeaderWidth: 0,
725745
uncompressedChuckSizeSum: 0,
726746
}
@@ -874,8 +894,8 @@ func (this *SQCloud) readResult() (*Result, error) {
874894
offset += bytesRead
875895

876896
result.rows = make([]ResultRow, int(N))
877-
result.ColumnNames = []string{"ARRAY"}
878-
result.ColumnWidth = []uint64{5}
897+
result.Name = []string{"ARRAY"}
898+
result.Width = []uint64{5}
879899
result.MaxHeaderWidth = 0
880900

881901
for row := uint64(0); row < N; row++ {
@@ -888,8 +908,8 @@ func (this *SQCloud) readResult() (*Result, error) {
888908
return nil, err
889909
default:
890910
columnLength := result.rows[row].columns[0].GetLength()
891-
if result.ColumnWidth[0] < columnLength {
892-
result.ColumnWidth[0] = columnLength
911+
if result.Width[0] < columnLength {
912+
result.Width[0] = columnLength
893913
}
894914
if result.MaxHeaderWidth < columnLength {
895915
result.MaxHeaderWidth = columnLength
@@ -954,30 +974,130 @@ func (this *SQCloud) readResult() (*Result, error) {
954974
// single chunk or first chunk of multiple chunks
955975
if IDX == 0 || IDX == 1 {
956976
result.rows = []ResultRow{}
957-
result.ColumnNames = make([]string, int(NCOLS))
958-
result.ColumnWidth = make([]uint64, int(NCOLS))
959977
result.MaxHeaderWidth = 0
960978

961-
for column := uint64(0); column < NCOLS; column++ { // Read in the column names, use the result.value as scratch variable
962-
switch val, bytesRead, err := chunk.readValueAt(offset); {
963-
case err != nil:
964-
return nil, err
965-
case !val.IsString():
966-
return nil, errors.New("Invalid Column name")
967-
default:
968-
result.ColumnNames[column] = val.GetString()
969-
result.ColumnWidth[column] = val.GetLength()
970-
if result.MaxHeaderWidth < result.ColumnWidth[column] {
971-
result.MaxHeaderWidth = result.ColumnWidth[column]
979+
if VERSION != ROWSET_TYPE_DATA_ONLY {
980+
// header is guarantee to contain column names
981+
result.Name = make([]string, int(NCOLS))
982+
result.Width = make([]uint64, int(NCOLS))
983+
for column := uint64(0); column < NCOLS; column++ { // Read in the column names, use the result.value as scratch variable
984+
switch val, bytesRead, err := chunk.readValueAt(offset); {
985+
case err != nil:
986+
return nil, err
987+
case !val.IsString():
988+
return nil, errors.New("Invalid Column name")
989+
default:
990+
result.Name[column] = val.GetString()
991+
result.Width[column] = val.GetLength()
992+
if result.MaxHeaderWidth < result.Width[column] {
993+
result.MaxHeaderWidth = result.Width[column]
994+
}
995+
offset += bytesRead
972996
}
973-
offset += bytesRead
974997
}
975-
}
976-
}
977998

978-
if VERSION != 1 {
979-
// not yet supported
980-
return nil, fmt.Errorf("Unsupported rowset version %d", VERSION)
999+
// check if additional metadata is contained
1000+
if VERSION == ROWSET_TYPE_METADATA_v1 {
1001+
result.DeclType = make([]string, int(NCOLS))
1002+
result.DbName = make([]string, int(NCOLS))
1003+
result.TblName = make([]string, int(NCOLS))
1004+
result.OrigName = make([]string, int(NCOLS))
1005+
result.Notnull = make([]int32, int(NCOLS))
1006+
result.PriKey = make([]int32, int(NCOLS))
1007+
result.Autoinc = make([]int32, int(NCOLS))
1008+
1009+
// column declared types
1010+
for column := uint64(0); column < NCOLS; column++ {
1011+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1012+
case err != nil:
1013+
return nil, err
1014+
case !val.IsString() && !val.IsNULL():
1015+
return nil, errors.New("Invalid decltype value")
1016+
default:
1017+
result.DeclType[column] = val.GetString()
1018+
offset += bytesRead
1019+
}
1020+
}
1021+
1022+
// column database names
1023+
for column := uint64(0); column < NCOLS; column++ {
1024+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1025+
case err != nil:
1026+
return nil, err
1027+
case !val.IsString() && !val.IsNULL():
1028+
return nil, errors.New("Invalid dbname value")
1029+
default:
1030+
result.DbName[column] = val.GetString()
1031+
offset += bytesRead
1032+
}
1033+
}
1034+
1035+
// column table names
1036+
for column := uint64(0); column < NCOLS; column++ {
1037+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1038+
case err != nil:
1039+
return nil, err
1040+
case !val.IsString() && !val.IsNULL():
1041+
return nil, errors.New("Invalid tblname value")
1042+
default:
1043+
result.TblName[column] = val.GetString()
1044+
offset += bytesRead
1045+
}
1046+
}
1047+
1048+
// column origin names
1049+
for column := uint64(0); column < NCOLS; column++ {
1050+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1051+
case err != nil:
1052+
return nil, err
1053+
case !val.IsString():
1054+
return nil, errors.New("Invalid origin name value")
1055+
default:
1056+
result.OrigName[column] = val.GetString()
1057+
offset += bytesRead
1058+
}
1059+
}
1060+
1061+
// column not null flag
1062+
for column := uint64(0); column < NCOLS; column++ {
1063+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1064+
case err != nil:
1065+
return nil, err
1066+
case !val.IsInteger():
1067+
return nil, errors.New("Invalid not null value")
1068+
default:
1069+
result.Notnull[column], _ = val.GetInt32()
1070+
offset += bytesRead
1071+
}
1072+
}
1073+
1074+
// column primary key flag
1075+
for column := uint64(0); column < NCOLS; column++ {
1076+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1077+
case err != nil:
1078+
return nil, err
1079+
case !val.IsInteger():
1080+
return nil, errors.New("Invalid primary key value")
1081+
default:
1082+
result.PriKey[column], _ = val.GetInt32()
1083+
offset += bytesRead
1084+
}
1085+
}
1086+
1087+
// column autoincrement key flag
1088+
for column := uint64(0); column < NCOLS; column++ {
1089+
switch val, bytesRead, err := chunk.readValueAt(offset); {
1090+
case err != nil:
1091+
return nil, err
1092+
case !val.IsInteger():
1093+
return nil, errors.New("Invalid autoinc value")
1094+
default:
1095+
result.Autoinc[column], _ = val.GetInt32()
1096+
offset += bytesRead
1097+
}
1098+
}
1099+
}
1100+
}
9811101
}
9821102

9831103
// read all the rows from this chunk
@@ -996,8 +1116,8 @@ func (this *SQCloud) readResult() (*Result, error) {
9961116
return nil, err
9971117
default:
9981118
columnLength := rows[row].columns[column].GetLength()
999-
if result.ColumnWidth[column] < columnLength {
1000-
result.ColumnWidth[column] = columnLength
1119+
if result.Width[column] < columnLength {
1120+
result.Width[column] = columnLength
10011121
}
10021122
if result.MaxHeaderWidth < columnLength {
10031123
result.MaxHeaderWidth = columnLength
@@ -1014,9 +1134,6 @@ func (this *SQCloud) readResult() (*Result, error) {
10141134

10151135
if Type == CMD_ROWSET {
10161136
return &result, nil
1017-
} // return if it is a rowset
1018-
if _, err := this.sendString("OK"); err != nil { // ask the server for the next chunk and loop (Thank's Andrea)
1019-
return nil, err
10201137
}
10211138

10221139
case CMD_RAWJSON:

row.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ func (this *ResultRow) GetMaxWidth(Column uint64) (uint64, error) {
116116
return this.result.GetMaxColumnWidth(Column)
117117
}
118118

119-
// Die folgenden Methoden sollten überflüssig sein...
120-
121119
// GetType returns the type of the value in column Column of this query result row.
122120
// The Column index is an unsigned int in the range of 0...GetNumberOfColumns() - 1.
123121
// Possible return types are: VALUE_INTEGER, VALUE_FLOAT, VALUE_TEXT, VALUE_BLOB, VALUE_NULL

0 commit comments

Comments
 (0)