Skip to content

Can't use type from the same package #819

Closed

Description

@maratori

Let's say I have following schema.

CREATE TABLE books (
    id UUID NOT NULL PRIMARY KEY,
    title VARCHAR NOT NULL,
    params JSONB NOT NULL
);

And I want to use following type for params column:

type BookParams struct {
	Foo string `json:"foo,omitempty"`
	Bar *int   `json:"bar,omitempty"`
}

func (p BookParams) Value() (driver.Value, error) {
	return json.Marshal(p)
}

func (p *BookParams) Scan(src interface{}) error {
	var source []byte
	switch t := src.(type) {
	case string:
		source = []byte(t)
	case []byte:
		source = t
	case nil:
		return nil
	default:
		return errors.Errorf("incompatible data type %T", src)
	}
	if len(source) == 0 {
		return nil
	}
	return json.Unmarshal(source, p)
}

I'd like to place BookParams type in the same package as code, generated by sqlc.
So I use following config:

version: "1"
packages:
  - name: "db"
    path: "./db"
    queries: "./db/queries.sql"
    schema: "./db/migrations/"
overrides:
  - column: "books.params"
    go_type: "BooksParams"

However it isn't possible because of error:

error parsing sqlc.yaml: Package override `go_type` specifier "BookParams" is not a Go basic type e.g. 'string'

The only way it works is to place type in the different package and to define full path, for example:

  - column: "books.params"
    go_type: "my.module/db/dbtype.BooksParams"

Activity

  1. kyleconroy commented on Jan 23, 2021

    @kyleconroy
    Collaborator

    @maratori This was actually fixed in #785, but I haven't updated the documentation in the README. You need to change how you're using the go_type value in the override. Also note that your example had a typo /s/BooksParams/BookParams.

    # sqlc.yaml
    version: "1"
    packages:
      - name: "db"
        path: "db"
        queries: "db/queries.sql"
        schema: "db/schema.sql"
    overrides:
      - column: "books.params"
        go_type:
          type: "BookParams"
    

    Here's the rest of the working code:

    $ tree .
    .
    ├── db
    │   ├── db.go
    │   ├── models.go
    │   ├── params.go
    │   ├── queries.sql
    │   └── schema.sql
    └── sqlc.yaml
    -- db/schema.sql
    
    CREATE TABLE books (
        id UUID NOT NULL PRIMARY KEY,
        title VARCHAR NOT NULL,
        params JSONB NOT NULL
    );
    -- db/queries.sql
    
    --name: ListBooks :many
    SELECT * FROM books;
    // db/params.go
    
    package db
    
    import (
    	"database/sql/driver"
    	"encoding/json"
    	"fmt"
    )
    
    type BookParams struct {
    	Foo string `json:"foo,omitempty"`
    	Bar *int   `json:"bar,omitempty"`
    }
    
    func (p BookParams) Value() (driver.Value, error) {
    	return json.Marshal(p)
    }
    
    func (p *BookParams) Scan(src interface{}) error {
    	var source []byte
    	switch t := src.(type) {
    	case string:
    		source = []byte(t)
    	case []byte:
    		source = t
    	case nil:
    		return nil
    	default:
    		return fmt.Errorf("incompatible data type %T", src)
    	}
    	if len(source) == 0 {
    		return nil
    	}
    	return json.Unmarshal(source, p)
    }

    The following works on my machine:

    $ sqlc generate
    $ go build ./...
  2. maratori commented on Jan 23, 2021

    @maratori
    Author

    @kyleconroy Thanks, it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions