diff --git a/db.go b/db.go index f4cdd5e3..9cd5a78b 100644 --- a/db.go +++ b/db.go @@ -1,6 +1,7 @@ package genji import ( + "bytes" "fmt" "github.com/asdine/genji/engine" @@ -350,3 +351,42 @@ func (t Table) RenameField(oldName, newName string) error { t.schema.Fields.Replace(oldName, sf) return t.schemas.Replace(t.name, t.schema) } + +// String displays the table as a csv compatible string. +func (t Table) String() string { + var buf bytes.Buffer + + if t.schema != nil { + fmt.Fprintf(&buf, "%s\n", t.schema.String()) + } + + err := t.Iterate(func(rowid []byte, r record.Record) error { + first := true + err := r.Iterate(func(f field.Field) error { + if !first { + buf.WriteString(", ") + } + first = false + + v, err := field.Decode(f) + if t.schema != nil { + fmt.Fprintf(&buf, "%#v", v) + } else { + fmt.Fprintf(&buf, "%s(%s): %#v", f.Name, f.Type, v) + } + return err + }) + if err != nil { + return err + } + + fmt.Fprintf(&buf, "\n") + return nil + }) + + if err != nil { + return err.Error() + } + + return buf.String() +} diff --git a/db_test.go b/db_test.go index e0e2627b..fc996b0e 100644 --- a/db_test.go +++ b/db_test.go @@ -1,6 +1,7 @@ package genji_test import ( + "fmt" "testing" "github.com/asdine/genji" @@ -74,3 +75,61 @@ func TestTable(t *testing.T) { require.NoError(t, err) }) } + +func TestTableString(t *testing.T) { + tests := []struct { + name string + withSchema bool + expected string + }{ + {"No schema", false, `name(String): "John 0", age(Int): 10 +name(String): "John 1", age(Int): 11 +name(String): "John 2", age(Int): 12 +`}, + {"With schema", true, `name(String), age(Int) +"John 0", 10 +"John 1", 11 +"John 2", 12 +`}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + db, err := genji.New(memory.NewEngine()) + require.NoError(t, err) + + err = db.Update(func(tx *genji.Tx) error { + if test.withSchema { + err := tx.CreateTableWithSchema("test", &record.Schema{ + Fields: []field.Field{ + {Name: "name", Type: field.String}, + {Name: "age", Type: field.Int}, + }, + }) + require.NoError(t, err) + } else { + err := tx.CreateTable("test") + require.NoError(t, err) + } + + tb, err := tx.Table("test") + require.NoError(t, err) + + for i := 0; i < 3; i++ { + rowid, err := tb.Insert(record.FieldBuffer([]field.Field{ + field.NewString("name", fmt.Sprintf("John %d", i)), + field.NewInt("age", 10+i), + })) + require.NoError(t, err) + require.NotNil(t, rowid) + } + + s := tb.(*genji.Table).String() + require.Equal(t, test.expected, s) + return nil + }) + require.NoError(t, err) + + }) + } +} diff --git a/record/schema.go b/record/schema.go index 0fcdff36..0a6b7ff8 100644 --- a/record/schema.go +++ b/record/schema.go @@ -77,7 +77,7 @@ func (s *Schema) Equal(other *Schema) bool { func (s *Schema) String() string { var b strings.Builder for i, f := range s.Fields { - b.WriteString(f.Name + ":" + f.Type.String()) + b.WriteString(f.Name + "(" + f.Type.String() + ")") if i+1 < len(s.Fields) { b.WriteString(", ") }