Compare commits

...

4 Commits

6 changed files with 92 additions and 14 deletions

View File

@ -35,8 +35,6 @@ func (c *compilerContext) renderBaseColumns(
c.renderComma(i) c.renderComma(i)
realColsRendered = append(realColsRendered, n) realColsRendered = append(realColsRendered, n)
colWithTable(c.w, ti.Name, cn) colWithTable(c.w, ti.Name, cn)
i++
continue
} else { } else {
switch { switch {
@ -44,27 +42,30 @@ func (c *compilerContext) renderBaseColumns(
if err := c.renderColumnSearchRank(sel, ti, col, i); err != nil { if err := c.renderColumnSearchRank(sel, ti, col, i); err != nil {
return nil, false, err return nil, false, err
} }
i++
case isSearch && strings.HasPrefix(cn, "search_headline_"): case isSearch && strings.HasPrefix(cn, "search_headline_"):
if err := c.renderColumnSearchHeadline(sel, ti, col, i); err != nil { if err := c.renderColumnSearchHeadline(sel, ti, col, i); err != nil {
return nil, false, err return nil, false, err
} }
i++
case cn == "__typename": case cn == "__typename":
if err := c.renderColumnTypename(sel, ti, col, i); err != nil { if err := c.renderColumnTypename(sel, ti, col, i); err != nil {
return nil, false, err return nil, false, err
} }
i++
case strings.HasSuffix(cn, "_cursor"):
continue
default: default:
if err := c.renderColumnFunction(sel, ti, col, i); err != nil { if err := c.renderColumnFunction(sel, ti, col, i); err != nil {
return nil, false, err return nil, false, err
} }
isAgg = true isAgg = true
i++
} }
} }
i++
} }
if isCursorPaged { if isCursorPaged {

View File

@ -93,7 +93,7 @@ func (co *Compiler) compileQuery(qc *qcode.QCode, w io.Writer, vars Variables) (
io.WriteString(c.w, `SELECT json_build_object(`) io.WriteString(c.w, `SELECT json_build_object(`)
for _, id := range qc.Roots { for _, id := range qc.Roots {
root := &qc.Selects[id] root := &qc.Selects[id]
if root.SkipRender { if root.SkipRender || len(root.Cols) == 0 {
continue continue
} }
@ -126,6 +126,10 @@ func (co *Compiler) compileQuery(qc *qcode.QCode, w io.Writer, vars Variables) (
if id < closeBlock { if id < closeBlock {
sel := &c.s[id] sel := &c.s[id]
if len(sel.Cols) == 0 {
continue
}
ti, err := c.schema.GetTable(sel.Name) ti, err := c.schema.GetTable(sel.Name)
if err != nil { if err != nil {
return 0, err return 0, err
@ -516,6 +520,10 @@ func (c *compilerContext) renderColumns(sel *qcode.Select, ti *DBTableInfo, skip
cn = col.Name[n:] cn = col.Name[n:]
} else { } else {
cn = col.Name cn = col.Name
if strings.HasSuffix(cn, "_cursor") {
continue
}
} }
if len(sel.Allowed) != 0 { if len(sel.Allowed) != 0 {

View File

@ -66,7 +66,14 @@ func NewDBSchema(info *DBInfo, aliases map[string][]string) (*DBSchema, error) {
} }
for i, t := range info.Tables { for i, t := range info.Tables {
err := schema.updateRelationships(t, info.Columns[i]) err := schema.firstDegreeRels(t, info.Columns[i])
if err != nil {
return nil, err
}
}
for i, t := range info.Tables {
err := schema.secondDegreeRels(t, info.Columns[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -131,8 +138,7 @@ func (s *DBSchema) addTable(
return nil return nil
} }
func (s *DBSchema) updateRelationships(t DBTable, cols []DBColumn) error { func (s *DBSchema) firstDegreeRels(t DBTable, cols []DBColumn) error {
jcols := make([]DBColumn, 0, len(cols))
ct := t.Key ct := t.Key
cti, ok := s.t[ct] cti, ok := s.t[ct]
if !ok { if !ok {
@ -230,6 +236,51 @@ func (s *DBSchema) updateRelationships(t DBTable, cols []DBColumn) error {
if err := s.SetRel(ft, ct, rel2); err != nil { if err := s.SetRel(ft, ct, rel2); err != nil {
return err return err
} }
}
return nil
}
func (s *DBSchema) secondDegreeRels(t DBTable, cols []DBColumn) error {
jcols := make([]DBColumn, 0, len(cols))
ct := t.Key
cti, ok := s.t[ct]
if !ok {
return fmt.Errorf("invalid foreign key table '%s'", ct)
}
for i := range cols {
c := cols[i]
if len(c.FKeyTable) == 0 {
continue
}
// Foreign key column name
ft := strings.ToLower(c.FKeyTable)
ti, ok := s.t[ft]
if !ok {
return fmt.Errorf("invalid foreign key table '%s'", ft)
}
// This is an embedded relationship like when a json/jsonb column
// is exposed as a table
if c.Name == c.FKeyTable && len(c.FKeyColID) == 0 {
continue
}
if len(c.FKeyColID) == 0 {
continue
}
// Foreign key column id
fcid := c.FKeyColID[0]
if _, ok := ti.ColIDMap[fcid]; !ok {
return fmt.Errorf("invalid foreign key column id '%d' for table '%s'",
fcid, ti.Name)
}
jcols = append(jcols, c) jcols = append(jcols, c)
} }
@ -322,6 +373,9 @@ func (s *DBSchema) GetTable(table string) (*DBTableInfo, error) {
} }
func (s *DBSchema) SetRel(child, parent string, rel *DBRel) error { func (s *DBSchema) SetRel(child, parent string, rel *DBRel) error {
sp := strings.ToLower(flect.Singularize(parent))
pp := strings.ToLower(flect.Pluralize(parent))
sc := strings.ToLower(flect.Singularize(child)) sc := strings.ToLower(flect.Singularize(child))
pc := strings.ToLower(flect.Pluralize(child)) pc := strings.ToLower(flect.Pluralize(child))
@ -333,9 +387,6 @@ func (s *DBSchema) SetRel(child, parent string, rel *DBRel) error {
s.rm[pc] = make(map[string]*DBRel) s.rm[pc] = make(map[string]*DBRel)
} }
sp := strings.ToLower(flect.Singularize(parent))
pp := strings.ToLower(flect.Pluralize(parent))
if _, ok := s.rm[sc][sp]; !ok { if _, ok := s.rm[sc][sp]; !ok {
s.rm[sc][sp] = rel s.rm[sc][sp] = rel
} }

View File

@ -19,6 +19,10 @@ func (rt RelType) String() string {
} }
func (re *DBRel) String() string { func (re *DBRel) String() string {
if re.Type == RelOneToManyThrough {
return fmt.Sprintf("'%s.%s' --(Through: %s)--> '%s.%s'",
re.Left.Table, re.Left.Col, re.Through, re.Right.Table, re.Right.Col)
}
return fmt.Sprintf("'%s.%s' --(%s)--> '%s.%s'", return fmt.Sprintf("'%s.%s' --(%s)--> '%s.%s'",
re.Left.Table, re.Left.Col, re.Type, re.Right.Table, re.Right.Col) re.Left.Table, re.Left.Col, re.Type, re.Right.Table, re.Right.Col)
} }

View File

@ -92,7 +92,14 @@ func getTestSchema() *DBSchema {
} }
for i, t := range tables { for i, t := range tables {
err := schema.updateRelationships(t, columns[i]) err := schema.firstDegreeRels(t, columns[i])
if err != nil {
log.Fatal(err)
}
}
for i, t := range tables {
err := schema.secondDegreeRels(t, columns[i])
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -339,6 +339,13 @@ func (p *Parser) parseFields(fields []Field) ([]Field, error) {
if p.peek(itemObjOpen) { if p.peek(itemObjOpen) {
p.ignore() p.ignore()
st.Push(f.ID) st.Push(f.ID)
} else if p.peek(itemObjClose) {
if st.Len() == 0 {
break
} else {
continue
}
} }
} }