can grab all queries required to fulfill a collector
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"gotemplate/internal/queue"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type DocumentController struct {
|
||||
@@ -20,7 +21,7 @@ func NewDocumentController(svc document.Service) *DocumentController {
|
||||
}
|
||||
|
||||
type DocumentQueryEvent struct {
|
||||
ID string `json:"id"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
}
|
||||
|
||||
func (s *DocumentController) Sync(ctx context.Context, config *queue.QueueConfig, msg *types.Message) error {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ func main() {
|
||||
log.Fatalf("Unable to load SDK config: %v", err)
|
||||
}
|
||||
|
||||
queueURL := env.GetRequired("QUEUE_URL")
|
||||
queueURL := env.GetFatal("QUEUE_URL")
|
||||
|
||||
sqsClient := sqs.NewFromConfig(cfg)
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DROP TYPE queryType;
|
||||
@@ -0,0 +1 @@
|
||||
CREATE TYPE queryType AS ENUM ('json_extractor');
|
||||
@@ -2,5 +2,5 @@ CREATE TABLE queries (
|
||||
id uuid primary key,
|
||||
latestVersion int not null default 1,
|
||||
activeVersion int not null default 1,
|
||||
type QueryType not null
|
||||
type queryType not null
|
||||
);
|
||||
@@ -1,6 +1,8 @@
|
||||
CREATE TABLE collectors (
|
||||
id uuid primary key,
|
||||
jobId uuid not null,
|
||||
minCleanVersion int not null default 1,
|
||||
minTextVersion int not null default 1,
|
||||
latestVersion int not null default 1,
|
||||
activeVersion int not null default 1
|
||||
);
|
||||
@@ -7,5 +7,5 @@ CREATE TABLE collectorQueries (
|
||||
removedVersion int,
|
||||
foreign key (queryId) references queries(id),
|
||||
foreign key (collectorId) references collectors(id),
|
||||
unique (collectorId, name, removedAt)
|
||||
unique (collectorId, name, removedVersion)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE results;
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE results (
|
||||
id uuid primary key,
|
||||
queryId uuid not null,
|
||||
documentId uuid not null,
|
||||
value TEXT,
|
||||
cleanVersion int not null,
|
||||
textVersion int not null,
|
||||
queryVersion int not null,
|
||||
foreign key (queryId) references queries(id),
|
||||
unique (queryId, documentId, cleanVersion, textVersion, queryVersion)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE requiredQueries;
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE requiredQueries (
|
||||
id uuid primary key,
|
||||
queryId uuid not null,
|
||||
requiredQueryId uuid not null,
|
||||
addedVersion int not null,
|
||||
removedVersion int,
|
||||
foreign key (queryId) references queries(id),
|
||||
foreign key (requiredQueryId) references queries(id),
|
||||
unique (queryId, requiredQueryId, removedVersion)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP VIEW activeQueryRequirements;
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE VIEW activeQueryRequirements AS
|
||||
SELECT q.id, q.type, q.activeVersion, rq.requiredQueryId
|
||||
FROM queries q
|
||||
JOIN requiredQueries rq ON q.id = rq.queryId
|
||||
WHERE q.activeVersion >= rq.addedVersion AND q.activeVersion < COALESCE(rq.removedVersion, q.activeVersion + 1);
|
||||
@@ -0,0 +1 @@
|
||||
DROP VIEW activeCollectorQueries;
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE VIEW activeCollectorQueries AS
|
||||
SELECT c.id, c.jobId, c.minCleanVersion, c.minTextVersion, c.activeVersion, cq.queryId
|
||||
FROM collectors c
|
||||
JOIN collectorQueries cq ON c.id = cq.collectorId
|
||||
WHERE c.activeVersion >= cq.addedVersion AND c.activeVersion < COALESCE(cq.removedVersion, c.activeVersion + 1);
|
||||
@@ -0,0 +1 @@
|
||||
DROP VIEW collectorQueryDependencyTree;
|
||||
@@ -0,0 +1,13 @@
|
||||
CREATE VIEW collectorQueryDependencyTree (id, jobId, type, requiredQueryId, queryVersion, minCleanVersion, minTextVersion) AS
|
||||
WITH RECURSIVE collectorQueryDependencyTree AS (
|
||||
SELECT aqc.id, cq.jobId, aqc.type, aqc.requiredQueryId, aqc.activeVersion as queryVersion, cq.minCleanVersion, cq.minTextVersion
|
||||
FROM activeQueryRequirements aqc
|
||||
JOIN activeCollectorQueries cq ON cq.queryId = aqc.id
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT q.id, acq.jobId, q.type, q.requiredQueryId, q.activeVersion as queryVersion, acq.minCleanVersion, acq.minTextVersion
|
||||
FROM activeQueryRequirements q
|
||||
JOIN collectorQueryDependencyTree acq on q.id = acq.requiredQueryId
|
||||
)
|
||||
SELECT DISTINCT * FROM collectorQueryDependencyTree;
|
||||
@@ -1,2 +1,2 @@
|
||||
-- name: GetCollectorFromJobId :one
|
||||
SELECT id, activeVersion FROM collectors where jobId = $1;
|
||||
-- name: GetQueriesFromJobID :many
|
||||
SELECT id, type, requiredQueryId, queryVersion, minCleanVersion, minTextVersion FROM collectorQueryDependencyTree WHERE jobId = $1;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- name: ListResultsByDocumentID :many
|
||||
SELECT id, queryId, cleanVersion, textVersion, queryVersion FROM results where documentId = $1;
|
||||
@@ -65,7 +65,7 @@ require (
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
|
||||
@@ -12,11 +12,11 @@ import (
|
||||
|
||||
func createConnectionString() string {
|
||||
driver := "postgres"
|
||||
dbUser := env.GetRequired("DB_USER")
|
||||
dbPass := env.GetRequired("DB_PASS")
|
||||
dbHost := env.GetRequired("DB_HOST")
|
||||
dbPort := env.GetRequired("DB_PORT")
|
||||
dbName := env.GetRequired("DB_NAME")
|
||||
dbUser := env.GetFatal("DB_USER")
|
||||
dbPass := env.GetFatal("DB_PASS")
|
||||
dbHost := env.GetFatal("DB_HOST")
|
||||
dbPort := env.GetFatal("DB_PORT")
|
||||
dbName := env.GetFatal("DB_NAME")
|
||||
connStr := fmt.Sprintf("%s://%s:%s@%s:%s/%s?sslmode=disable", driver, dbUser, dbPass, dbHost, dbPort, dbName)
|
||||
|
||||
return connStr
|
||||
|
||||
@@ -14,11 +14,11 @@ import (
|
||||
)
|
||||
|
||||
func createDB() {
|
||||
dbUser := env.GetRequired("DB_USER")
|
||||
dbPass := env.GetRequired("DB_PASS")
|
||||
dbHost := env.GetRequired("DB_HOST")
|
||||
dbPort := env.GetRequired("DB_PORT")
|
||||
dbName := env.GetRequired("DB_NAME")
|
||||
dbUser := env.GetFatal("DB_USER")
|
||||
dbPass := env.GetFatal("DB_PASS")
|
||||
dbHost := env.GetFatal("DB_HOST")
|
||||
dbPort := env.GetFatal("DB_PORT")
|
||||
dbName := env.GetFatal("DB_NAME")
|
||||
driver := "postgres"
|
||||
connStr := fmt.Sprintf("%s://%s:%s@%s:%s?sslmode=disable", driver, dbUser, dbPass, dbHost, dbPort)
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: collector.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const getQueriesFromJobID = `-- name: GetQueriesFromJobID :many
|
||||
SELECT id, type, requiredQueryId, queryVersion, minCleanVersion, minTextVersion FROM collectorQueryDependencyTree WHERE jobId = $1
|
||||
`
|
||||
|
||||
type GetQueriesFromJobIDRow struct {
|
||||
ID pgtype.UUID
|
||||
Type Querytype
|
||||
Requiredqueryid pgtype.UUID
|
||||
Queryversion int32
|
||||
Mincleanversion int32
|
||||
Mintextversion int32
|
||||
}
|
||||
|
||||
func (q *Queries) GetQueriesFromJobID(ctx context.Context, jobid pgtype.UUID) ([]GetQueriesFromJobIDRow, error) {
|
||||
rows, err := q.db.Query(ctx, getQueriesFromJobID, jobid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetQueriesFromJobIDRow
|
||||
for rows.Next() {
|
||||
var i GetQueriesFromJobIDRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Type,
|
||||
&i.Requiredqueryid,
|
||||
&i.Queryversion,
|
||||
&i.Mincleanversion,
|
||||
&i.Mintextversion,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@@ -4,6 +4,119 @@
|
||||
|
||||
package repository
|
||||
|
||||
type Name struct {
|
||||
Name string
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type Querytype string
|
||||
|
||||
const (
|
||||
QuerytypeJsonExtractor Querytype = "json_extractor"
|
||||
)
|
||||
|
||||
func (e *Querytype) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = Querytype(s)
|
||||
case string:
|
||||
*e = Querytype(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for Querytype: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullQuerytype struct {
|
||||
Querytype Querytype
|
||||
Valid bool // Valid is true if Querytype is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullQuerytype) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.Querytype, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.Querytype.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullQuerytype) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.Querytype), nil
|
||||
}
|
||||
|
||||
type Activecollectorquery struct {
|
||||
ID pgtype.UUID
|
||||
Jobid pgtype.UUID
|
||||
Mincleanversion int32
|
||||
Mintextversion int32
|
||||
Activeversion int32
|
||||
Queryid pgtype.UUID
|
||||
}
|
||||
|
||||
type Activequeryrequirement struct {
|
||||
ID pgtype.UUID
|
||||
Type Querytype
|
||||
Activeversion int32
|
||||
Requiredqueryid pgtype.UUID
|
||||
}
|
||||
|
||||
type Collector struct {
|
||||
ID pgtype.UUID
|
||||
Jobid pgtype.UUID
|
||||
Mincleanversion int32
|
||||
Mintextversion int32
|
||||
Latestversion int32
|
||||
Activeversion int32
|
||||
}
|
||||
|
||||
type Collectorquery struct {
|
||||
ID pgtype.UUID
|
||||
Collectorid pgtype.UUID
|
||||
Name string
|
||||
Queryid pgtype.UUID
|
||||
Addedversion int32
|
||||
Removedversion pgtype.Int4
|
||||
}
|
||||
|
||||
type Collectorquerydependencytree struct {
|
||||
ID pgtype.UUID
|
||||
Jobid pgtype.UUID
|
||||
Type Querytype
|
||||
Requiredqueryid pgtype.UUID
|
||||
Queryversion int32
|
||||
Mincleanversion int32
|
||||
Mintextversion int32
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
ID pgtype.UUID
|
||||
Latestversion int32
|
||||
Activeversion int32
|
||||
Type Querytype
|
||||
}
|
||||
|
||||
type Requiredquery struct {
|
||||
ID pgtype.UUID
|
||||
Queryid pgtype.UUID
|
||||
Requiredqueryid pgtype.UUID
|
||||
Addedversion int32
|
||||
Removedversion pgtype.Int4
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
ID pgtype.UUID
|
||||
Queryid pgtype.UUID
|
||||
Documentid pgtype.UUID
|
||||
Value pgtype.Text
|
||||
Cleanversion int32
|
||||
Textversion int32
|
||||
Queryversion int32
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: name.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const addName = `-- name: AddName :exec
|
||||
INSERT INTO names (name) VALUES ($1)
|
||||
`
|
||||
|
||||
func (q *Queries) AddName(ctx context.Context, name string) error {
|
||||
_, err := q.db.Exec(ctx, addName, name)
|
||||
return err
|
||||
}
|
||||
|
||||
const getName = `-- name: GetName :one
|
||||
SELECT name as dbName FROM names where name = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetName(ctx context.Context, name string) (string, error) {
|
||||
row := q.db.QueryRow(ctx, getName, name)
|
||||
var dbname string
|
||||
err := row.Scan(&dbname)
|
||||
return dbname, err
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: result.sql
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const listResultsByDocumentID = `-- name: ListResultsByDocumentID :many
|
||||
SELECT id, queryId, cleanVersion, textVersion, queryVersion FROM results where documentId = $1
|
||||
`
|
||||
|
||||
type ListResultsByDocumentIDRow struct {
|
||||
ID pgtype.UUID
|
||||
Queryid pgtype.UUID
|
||||
Cleanversion int32
|
||||
Textversion int32
|
||||
Queryversion int32
|
||||
}
|
||||
|
||||
func (q *Queries) ListResultsByDocumentID(ctx context.Context, documentid pgtype.UUID) ([]ListResultsByDocumentIDRow, error) {
|
||||
rows, err := q.db.Query(ctx, listResultsByDocumentID, documentid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ListResultsByDocumentIDRow
|
||||
for rows.Next() {
|
||||
var i ListResultsByDocumentIDRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Queryid,
|
||||
&i.Cleanversion,
|
||||
&i.Textversion,
|
||||
&i.Queryversion,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func ToDBUUID(id uuid.UUID) (pgtype.UUID, error) {
|
||||
var dbID pgtype.UUID
|
||||
err := dbID.Scan(id.String())
|
||||
if err != nil {
|
||||
return pgtype.UUID{}, err
|
||||
}
|
||||
|
||||
return dbID, nil
|
||||
}
|
||||
@@ -2,7 +2,11 @@ package document
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gotemplate/internal/database"
|
||||
"gotemplate/internal/database/repository"
|
||||
"log"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
@@ -10,9 +14,9 @@ type Service struct {
|
||||
}
|
||||
|
||||
type Document struct {
|
||||
ID string `json:"id"`
|
||||
JobID string `json:"jobId"`
|
||||
Name string `json:"name"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
JobID uuid.UUID `json:"jobId"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func New(ctx context.Context, db *repository.Queries) *Service {
|
||||
@@ -22,9 +26,43 @@ func New(ctx context.Context, db *repository.Queries) *Service {
|
||||
}
|
||||
|
||||
func (s *Service) Sync(ctx context.Context, doc Document) error {
|
||||
// Check if collector exists for doc and is synced
|
||||
// Check if job set up
|
||||
// If not find all outputs and see if any are out of sync/missing
|
||||
// create dependency tree - if sync triggered, sync all dependent outputs by using queue
|
||||
jobID, err := database.ToDBUUID(doc.JobID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queries, err := s.db.GetQueriesFromJobID(ctx, jobID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
docID, err := database.ToDBUUID(doc.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
results, err := s.db.ListResultsByDocumentID(ctx, docID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, query := range queries {
|
||||
isSynced := false
|
||||
for _, result := range results {
|
||||
if result.Queryid != query.ID {
|
||||
continue
|
||||
}
|
||||
isSynced = result.Cleanversion >= query.Mincleanversion && result.Textversion >= query.Mintextversion && result.Queryversion != query.Queryversion
|
||||
break
|
||||
}
|
||||
if isSynced {
|
||||
continue
|
||||
}
|
||||
log.Print("TODO sync me pls")
|
||||
// Check if exists and synced
|
||||
// IF NOT synced then add to queue, as well as all dependents recursively
|
||||
}
|
||||
// TODO what to do with results that are not used
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Vendored
+9
-8
@@ -1,24 +1,25 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func GetRequired(name string) string {
|
||||
value, exists := os.LookupEnv(name)
|
||||
if !exists {
|
||||
log.Fatal("Environment variable not set: ", name)
|
||||
func GetFatal(name string) string {
|
||||
value, err := Get(name)
|
||||
if err != nil {
|
||||
log.Panic(err.Error())
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func Get(name string) string {
|
||||
func Get(name string) (string, error) {
|
||||
value, exists := os.LookupEnv(name)
|
||||
if !exists {
|
||||
log.Print("Environment variable not set: ", name)
|
||||
if !exists || value == "" {
|
||||
return "", fmt.Errorf("environment variable not set: %s", name)
|
||||
}
|
||||
|
||||
return value
|
||||
return value, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package database_test
|
||||
|
||||
import (
|
||||
"gotemplate/internal/database"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestToDBUUID(t *testing.T) {
|
||||
id := uuid.New()
|
||||
|
||||
dbID, err := database.ToDBUUID(id)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, true, dbID.Valid)
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package name_test
|
||||
package document_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gotemplate/internal/database"
|
||||
"gotemplate/internal/database/repository"
|
||||
"gotemplate/internal/document"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/pashagolub/pgxmock/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -22,11 +25,26 @@ func TestSync(t *testing.T) {
|
||||
queries := repository.New(db)
|
||||
svc := document.New(ctx, queries)
|
||||
doc := document.Document{
|
||||
ID: "1",
|
||||
Name: "document_name",
|
||||
ID: uuid.New(),
|
||||
JobID: uuid.New(),
|
||||
Name: "document_name",
|
||||
}
|
||||
|
||||
db.ExpectExec("INSERT INTO names (name) VALUES ($1)")
|
||||
dbJobID, err := database.ToDBUUID(doc.JobID)
|
||||
assert.Nil(t, err)
|
||||
db.ExpectQuery("name: GetQueriesFromJobID :many").WithArgs(dbJobID).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"id", "type", "requiredQueryId", "queryVersion", "minCleanVersion", "minTextVersion"}).
|
||||
AddRow(pgtype.UUID{}, repository.QuerytypeJsonExtractor, pgtype.UUID{}, int32(1), int32(1), int32(1)),
|
||||
)
|
||||
|
||||
dbDocID, err := database.ToDBUUID(doc.ID)
|
||||
assert.Nil(t, err)
|
||||
db.ExpectQuery("name: ListResultsByDocumentID :many").WithArgs(dbDocID).
|
||||
WillReturnRows(
|
||||
pgxmock.NewRows([]string{"id", "queryId", "cleanVersion", "textVersion", "queryVersion"}).
|
||||
AddRow(pgtype.UUID{}, pgtype.UUID{}, int32(1), int32(1), int32(1)),
|
||||
)
|
||||
|
||||
err = svc.Sync(ctx, doc)
|
||||
|
||||
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
package env_test
|
||||
|
||||
import (
|
||||
"gotemplate/internal/env"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
name := "test_get_env_var_does_not_exist"
|
||||
|
||||
value := "value"
|
||||
os.Setenv(name, value)
|
||||
|
||||
returnValue, err := env.Get(name)
|
||||
|
||||
assert.Equal(t, value, returnValue)
|
||||
assert.Nil(t, err)
|
||||
|
||||
value = ""
|
||||
os.Setenv(name, value)
|
||||
|
||||
returnValue, err = env.Get(name)
|
||||
|
||||
assert.Equal(t, value, returnValue)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package env_test
|
||||
|
||||
import (
|
||||
"gotemplate/internal/env"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetFatal(t *testing.T) {
|
||||
name := "test_get_env_var_does_not_exist"
|
||||
|
||||
value := "value"
|
||||
os.Setenv(name, value)
|
||||
|
||||
returnValue := env.GetFatal(name)
|
||||
|
||||
assert.Equal(t, value, returnValue)
|
||||
|
||||
value = ""
|
||||
os.Setenv(name, value)
|
||||
|
||||
assert.Panics(t, func() { env.GetFatal(name) })
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package winterm
|
||||
|
||||
+20
-19
@@ -15,26 +15,26 @@ import (
|
||||
// When defining struct types. the `document` struct tag can be used to control how the value will be
|
||||
// marshaled into the resulting protocol document.
|
||||
//
|
||||
// // Field is ignored
|
||||
// Field int `document:"-"`
|
||||
// // Field is ignored
|
||||
// Field int `document:"-"`
|
||||
//
|
||||
// // Field object of key "myName"
|
||||
// Field int `document:"myName"`
|
||||
// // Field object of key "myName"
|
||||
// Field int `document:"myName"`
|
||||
//
|
||||
// // Field object key of key "myName", and
|
||||
// // Field is omitted if the field is a zero value for the type.
|
||||
// Field int `document:"myName,omitempty"`
|
||||
// // Field object key of key "myName", and
|
||||
// // Field is omitted if the field is a zero value for the type.
|
||||
// Field int `document:"myName,omitempty"`
|
||||
//
|
||||
// // Field object key of "Field", and
|
||||
// // Field is omitted if the field is a zero value for the type.
|
||||
// Field int `document:",omitempty"`
|
||||
// // Field object key of "Field", and
|
||||
// // Field is omitted if the field is a zero value for the type.
|
||||
// Field int `document:",omitempty"`
|
||||
//
|
||||
// All struct fields, including anonymous fields, are marshaled unless the
|
||||
// any of the following conditions are meet.
|
||||
//
|
||||
// - the field is not exported
|
||||
// - document field tag is "-"
|
||||
// - document field tag specifies "omitempty", and is a zero value.
|
||||
// - the field is not exported
|
||||
// - document field tag is "-"
|
||||
// - document field tag specifies "omitempty", and is a zero value.
|
||||
//
|
||||
// Pointer and interface values are encoded as the value pointed to or
|
||||
// contained in the interface. A nil value encodes as a null
|
||||
@@ -63,12 +63,13 @@ type Marshaler interface {
|
||||
//
|
||||
// Both generic interface{} and concrete types are valid unmarshal destination types. When unmarshaling a document
|
||||
// into an empty interface the Unmarshaler will store one of these values:
|
||||
// bool, for boolean values
|
||||
// document.Number, for arbitrary-precision numbers (int64, float64, big.Int, big.Float)
|
||||
// string, for string values
|
||||
// []interface{}, for array values
|
||||
// map[string]interface{}, for objects
|
||||
// nil, for null values
|
||||
//
|
||||
// bool, for boolean values
|
||||
// document.Number, for arbitrary-precision numbers (int64, float64, big.Int, big.Float)
|
||||
// string, for string values
|
||||
// []interface{}, for array values
|
||||
// map[string]interface{}, for objects
|
||||
// nil, for null values
|
||||
//
|
||||
// When unmarshaling, any error that occurs will halt the unmarshal and return the error.
|
||||
type Unmarshaler interface {
|
||||
|
||||
+5
-5
@@ -4,21 +4,21 @@ shape serializer function in which a xml.Value will be passed around.
|
||||
|
||||
Resources followed: https://smithy.io/2.0/spec/protocol-traits.html#xml-bindings
|
||||
|
||||
Member Element
|
||||
# Member Element
|
||||
|
||||
Member element should be used to encode xml shapes into xml elements except for flattened xml shapes. Member element
|
||||
write their own element start tag. These elements should always be closed.
|
||||
|
||||
Flattened Element
|
||||
# Flattened Element
|
||||
|
||||
Flattened element should be used to encode shapes marked with flattened trait into xml elements. Flattened element
|
||||
do not write a start tag, and thus should not be closed.
|
||||
|
||||
Simple types encoding
|
||||
# Simple types encoding
|
||||
|
||||
All simple type methods on value such as String(), Long() etc; auto close the associated member element.
|
||||
|
||||
Array
|
||||
# Array
|
||||
|
||||
Array returns the collection encoder. It has two modes, wrapped and flattened encoding.
|
||||
|
||||
@@ -32,7 +32,7 @@ If a shape is marked as flattened, Array() will use the shape element name as wr
|
||||
|
||||
<flattenedAarray>apple</flattenedArray><flattenedArray>tree</flattenedArray>
|
||||
|
||||
Map
|
||||
# Map
|
||||
|
||||
Map is the map encoder. It has two modes, wrapped and flattened encoding.
|
||||
|
||||
|
||||
+10
-10
@@ -14,7 +14,7 @@
|
||||
// handler. A handler could be something like an HTTP Client that round trips an
|
||||
// API operation over HTTP.
|
||||
//
|
||||
// Smithy Middleware Stack
|
||||
// # Smithy Middleware Stack
|
||||
//
|
||||
// A Stack is a collection of middleware that wrap a handler. The stack can be
|
||||
// broken down into discreet steps. Each step may contain zero or more middleware
|
||||
@@ -48,20 +48,20 @@
|
||||
// the request message. Deserializes the response into a structured type or
|
||||
// error above stacks can react to.
|
||||
//
|
||||
// Adding Middleware to a Stack Step
|
||||
// # Adding Middleware to a Stack Step
|
||||
//
|
||||
// Middleware can be added to a step front or back, or relative, by name, to an
|
||||
// existing middleware in that stack. If a middleware does not have a name, a
|
||||
// unique name will be generated at the middleware and be added to the step.
|
||||
//
|
||||
// // Create middleware stack
|
||||
// stack := middleware.NewStack()
|
||||
// // Create middleware stack
|
||||
// stack := middleware.NewStack()
|
||||
//
|
||||
// // Add middleware to stack steps
|
||||
// stack.Initialize.Add(paramValidationMiddleware, middleware.After)
|
||||
// stack.Serialize.Add(marshalOperationFoo, middleware.After)
|
||||
// stack.Deserialize.Add(unmarshalOperationFoo, middleware.After)
|
||||
// // Add middleware to stack steps
|
||||
// stack.Initialize.Add(paramValidationMiddleware, middleware.After)
|
||||
// stack.Serialize.Add(marshalOperationFoo, middleware.After)
|
||||
// stack.Deserialize.Add(unmarshalOperationFoo, middleware.After)
|
||||
//
|
||||
// // Invoke middleware on handler.
|
||||
// resp, err := stack.HandleMiddleware(ctx, req.Input, clientHandler)
|
||||
// // Invoke middleware on handler.
|
||||
// resp, err := stack.HandleMiddleware(ctx, req.Input, clientHandler)
|
||||
package middleware
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import (
|
||||
// Steps are composed as middleware around the underlying handler in the
|
||||
// following order:
|
||||
//
|
||||
// Initialize -> Serialize -> Build -> Finalize -> Deserialize -> Handler
|
||||
// Initialize -> Serialize -> Build -> Finalize -> Deserialize -> Handler
|
||||
//
|
||||
// Any middleware within the chain may choose to stop and return an error or
|
||||
// response. Since the middleware decorate the handler like a call stack, each
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
// Middleware that does not need to react to an input, or result must forward
|
||||
// along the input down the chain, or return the result back up the chain.
|
||||
//
|
||||
// Initialize <- Serialize -> Build -> Finalize <- Deserialize <- Handler
|
||||
// Initialize <- Serialize -> Build -> Finalize <- Deserialize <- Handler
|
||||
type Stack struct {
|
||||
// Initialize prepares the input, and sets any default parameters as
|
||||
// needed, (e.g. idempotency token, and presigned URLs).
|
||||
|
||||
+20
-18
@@ -11,17 +11,17 @@ period for each retry attempt using a randomization function that grows exponent
|
||||
|
||||
NextBackOff() is calculated using the following formula:
|
||||
|
||||
randomized interval =
|
||||
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
||||
randomized interval =
|
||||
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
|
||||
|
||||
In other words NextBackOff() will range between the randomization factor
|
||||
percentage below and above the retry interval.
|
||||
|
||||
For example, given the following parameters:
|
||||
|
||||
RetryInterval = 2
|
||||
RandomizationFactor = 0.5
|
||||
Multiplier = 2
|
||||
RetryInterval = 2
|
||||
RandomizationFactor = 0.5
|
||||
Multiplier = 2
|
||||
|
||||
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
|
||||
multiplied by the exponential, that is, between 2 and 6 seconds.
|
||||
@@ -36,18 +36,18 @@ The elapsed time can be reset by calling Reset().
|
||||
Example: Given the following default arguments, for 10 tries the sequence will be,
|
||||
and assuming we go over the MaxElapsedTime on the 10th try:
|
||||
|
||||
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
||||
Request # RetryInterval (seconds) Randomized Interval (seconds)
|
||||
|
||||
1 0.5 [0.25, 0.75]
|
||||
2 0.75 [0.375, 1.125]
|
||||
3 1.125 [0.562, 1.687]
|
||||
4 1.687 [0.8435, 2.53]
|
||||
5 2.53 [1.265, 3.795]
|
||||
6 3.795 [1.897, 5.692]
|
||||
7 5.692 [2.846, 8.538]
|
||||
8 8.538 [4.269, 12.807]
|
||||
9 12.807 [6.403, 19.210]
|
||||
10 19.210 backoff.Stop
|
||||
1 0.5 [0.25, 0.75]
|
||||
2 0.75 [0.375, 1.125]
|
||||
3 1.125 [0.562, 1.687]
|
||||
4 1.687 [0.8435, 2.53]
|
||||
5 2.53 [1.265, 3.795]
|
||||
6 3.795 [1.897, 5.692]
|
||||
7 5.692 [2.846, 8.538]
|
||||
8 8.538 [4.269, 12.807]
|
||||
9 12.807 [6.403, 19.210]
|
||||
10 19.210 backoff.Stop
|
||||
|
||||
Note: Implementation is not thread-safe.
|
||||
*/
|
||||
@@ -167,7 +167,8 @@ func (b *ExponentialBackOff) Reset() {
|
||||
}
|
||||
|
||||
// NextBackOff calculates the next backoff interval using the formula:
|
||||
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
||||
//
|
||||
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
|
||||
func (b *ExponentialBackOff) NextBackOff() time.Duration {
|
||||
// Make sure we have not gone over the maximum elapsed time.
|
||||
elapsed := b.GetElapsedTime()
|
||||
@@ -200,7 +201,8 @@ func (b *ExponentialBackOff) incrementCurrentInterval() {
|
||||
}
|
||||
|
||||
// Returns a random value from the following interval:
|
||||
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
||||
//
|
||||
// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
|
||||
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
|
||||
if randomizationFactor == 0 {
|
||||
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
|
||||
|
||||
+1
@@ -18,6 +18,7 @@
|
||||
// tag is deprecated and thus should not be used.
|
||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||
//go:build !js && !appengine && !safe && !disableunsafe && go1.4
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
package spew
|
||||
|
||||
+1
@@ -16,6 +16,7 @@
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
//go:build js || appengine || safe || disableunsafe || !go1.4
|
||||
// +build js appengine safe disableunsafe !go1.4
|
||||
|
||||
package spew
|
||||
|
||||
+15
-15
@@ -254,15 +254,15 @@ pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
- Pointers are dereferenced and followed
|
||||
- Circular data structures are detected and handled properly
|
||||
- Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
- Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by modifying the public members
|
||||
of c. See ConfigState for options documentation.
|
||||
@@ -295,12 +295,12 @@ func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{})
|
||||
|
||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||
//
|
||||
// Indent: " "
|
||||
// MaxDepth: 0
|
||||
// DisableMethods: false
|
||||
// DisablePointerMethods: false
|
||||
// ContinueOnMethod: false
|
||||
// SortKeys: false
|
||||
// Indent: " "
|
||||
// MaxDepth: 0
|
||||
// DisableMethods: false
|
||||
// DisablePointerMethods: false
|
||||
// ContinueOnMethod: false
|
||||
// SortKeys: false
|
||||
func NewDefaultConfig() *ConfigState {
|
||||
return &ConfigState{Indent: " "}
|
||||
}
|
||||
|
||||
+67
-61
@@ -21,35 +21,36 @@ debugging.
|
||||
A quick overview of the additional features spew provides over the built-in
|
||||
printing facilities for Go data types are as follows:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output (only when using
|
||||
Dump style)
|
||||
- Pointers are dereferenced and followed
|
||||
- Circular data structures are detected and handled properly
|
||||
- Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
- Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output (only when using
|
||||
Dump style)
|
||||
|
||||
There are two different approaches spew allows for dumping Go data structures:
|
||||
|
||||
* Dump style which prints with newlines, customizable indentation,
|
||||
and additional debug information such as types and all pointer addresses
|
||||
used to indirect to the final value
|
||||
* A custom Formatter interface that integrates cleanly with the standard fmt
|
||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||
similar to the default %v while providing the additional functionality
|
||||
outlined above and passing unsupported format verbs such as %x and %q
|
||||
along to fmt
|
||||
- Dump style which prints with newlines, customizable indentation,
|
||||
and additional debug information such as types and all pointer addresses
|
||||
used to indirect to the final value
|
||||
- A custom Formatter interface that integrates cleanly with the standard fmt
|
||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||
similar to the default %v while providing the additional functionality
|
||||
outlined above and passing unsupported format verbs such as %x and %q
|
||||
along to fmt
|
||||
|
||||
Quick Start
|
||||
# Quick Start
|
||||
|
||||
This section demonstrates how to quickly get started with spew. See the
|
||||
sections below for further details on formatting and configuration options.
|
||||
|
||||
To dump a variable with full newlines, indentation, type, and pointer
|
||||
information use Dump, Fdump, or Sdump:
|
||||
|
||||
spew.Dump(myVar1, myVar2, ...)
|
||||
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
@@ -58,12 +59,13 @@ Alternatively, if you would prefer to use format strings with a compacted inline
|
||||
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
||||
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
||||
%#+v (adds types and pointer addresses):
|
||||
|
||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
|
||||
Configuration Options
|
||||
# Configuration Options
|
||||
|
||||
Configuration of spew is handled by fields in the ConfigState type. For
|
||||
convenience, all of the top-level functions use a global state available
|
||||
@@ -74,51 +76,52 @@ equivalent to the top-level functions. This allows concurrent configuration
|
||||
options. See the ConfigState documentation for more details.
|
||||
|
||||
The following configuration options are available:
|
||||
* Indent
|
||||
String to use for each indentation level for Dump functions.
|
||||
It is a single space by default. A popular alternative is "\t".
|
||||
|
||||
* MaxDepth
|
||||
Maximum number of levels to descend into nested data structures.
|
||||
There is no limit by default.
|
||||
- Indent
|
||||
String to use for each indentation level for Dump functions.
|
||||
It is a single space by default. A popular alternative is "\t".
|
||||
|
||||
* DisableMethods
|
||||
Disables invocation of error and Stringer interface methods.
|
||||
Method invocation is enabled by default.
|
||||
- MaxDepth
|
||||
Maximum number of levels to descend into nested data structures.
|
||||
There is no limit by default.
|
||||
|
||||
* DisablePointerMethods
|
||||
Disables invocation of error and Stringer interface methods on types
|
||||
which only accept pointer receivers from non-pointer variables.
|
||||
Pointer method invocation is enabled by default.
|
||||
- DisableMethods
|
||||
Disables invocation of error and Stringer interface methods.
|
||||
Method invocation is enabled by default.
|
||||
|
||||
* DisablePointerAddresses
|
||||
DisablePointerAddresses specifies whether to disable the printing of
|
||||
pointer addresses. This is useful when diffing data structures in tests.
|
||||
- DisablePointerMethods
|
||||
Disables invocation of error and Stringer interface methods on types
|
||||
which only accept pointer receivers from non-pointer variables.
|
||||
Pointer method invocation is enabled by default.
|
||||
|
||||
* DisableCapacities
|
||||
DisableCapacities specifies whether to disable the printing of
|
||||
capacities for arrays, slices, maps and channels. This is useful when
|
||||
diffing data structures in tests.
|
||||
- DisablePointerAddresses
|
||||
DisablePointerAddresses specifies whether to disable the printing of
|
||||
pointer addresses. This is useful when diffing data structures in tests.
|
||||
|
||||
* ContinueOnMethod
|
||||
Enables recursion into types after invoking error and Stringer interface
|
||||
methods. Recursion after method invocation is disabled by default.
|
||||
- DisableCapacities
|
||||
DisableCapacities specifies whether to disable the printing of
|
||||
capacities for arrays, slices, maps and channels. This is useful when
|
||||
diffing data structures in tests.
|
||||
|
||||
* SortKeys
|
||||
Specifies map keys should be sorted before being printed. Use
|
||||
this to have a more deterministic, diffable output. Note that
|
||||
only native types (bool, int, uint, floats, uintptr and string)
|
||||
and types which implement error or Stringer interfaces are
|
||||
supported with other types sorted according to the
|
||||
reflect.Value.String() output which guarantees display
|
||||
stability. Natural map order is used by default.
|
||||
- ContinueOnMethod
|
||||
Enables recursion into types after invoking error and Stringer interface
|
||||
methods. Recursion after method invocation is disabled by default.
|
||||
|
||||
* SpewKeys
|
||||
Specifies that, as a last resort attempt, map keys should be
|
||||
spewed to strings and sorted by those strings. This is only
|
||||
considered if SortKeys is true.
|
||||
- SortKeys
|
||||
Specifies map keys should be sorted before being printed. Use
|
||||
this to have a more deterministic, diffable output. Note that
|
||||
only native types (bool, int, uint, floats, uintptr and string)
|
||||
and types which implement error or Stringer interfaces are
|
||||
supported with other types sorted according to the
|
||||
reflect.Value.String() output which guarantees display
|
||||
stability. Natural map order is used by default.
|
||||
|
||||
Dump Usage
|
||||
- SpewKeys
|
||||
Specifies that, as a last resort attempt, map keys should be
|
||||
spewed to strings and sorted by those strings. This is only
|
||||
considered if SortKeys is true.
|
||||
|
||||
# Dump Usage
|
||||
|
||||
Simply call spew.Dump with a list of variables you want to dump:
|
||||
|
||||
@@ -133,7 +136,7 @@ A third option is to call spew.Sdump to get the formatted output as a string:
|
||||
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
|
||||
Sample Dump Output
|
||||
# Sample Dump Output
|
||||
|
||||
See the Dump example for details on the setup of the types and variables being
|
||||
shown here.
|
||||
@@ -150,13 +153,14 @@ shown here.
|
||||
|
||||
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
||||
command as shown.
|
||||
|
||||
([]uint8) (len=32 cap=32) {
|
||||
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||
00000020 31 32 |12|
|
||||
}
|
||||
|
||||
Custom Formatter
|
||||
# Custom Formatter
|
||||
|
||||
Spew provides a custom formatter that implements the fmt.Formatter interface
|
||||
so that it integrates cleanly with standard fmt package printing functions. The
|
||||
@@ -170,7 +174,7 @@ standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Custom Formatter Usage
|
||||
# Custom Formatter Usage
|
||||
|
||||
The simplest way to make use of the spew custom formatter is to call one of the
|
||||
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
||||
@@ -184,15 +188,17 @@ functions have syntax you are most likely already familiar with:
|
||||
|
||||
See the Index for the full list convenience functions.
|
||||
|
||||
Sample Formatter Output
|
||||
# Sample Formatter Output
|
||||
|
||||
Double pointer to a uint8:
|
||||
|
||||
%v: <**>5
|
||||
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
||||
%#v: (**uint8)5
|
||||
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
||||
|
||||
Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||
|
||||
%v: <*>{1 <*><shown>}
|
||||
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
||||
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
||||
@@ -201,7 +207,7 @@ Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||
See the Printf example for details on the setup of variables being shown
|
||||
here.
|
||||
|
||||
Errors
|
||||
# Errors
|
||||
|
||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||
detects them and handles them internally by printing the panic information
|
||||
|
||||
+9
-9
@@ -488,15 +488,15 @@ pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
- Pointers are dereferenced and followed
|
||||
- Circular data structures are detected and handled properly
|
||||
- Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
- Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
- Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by an exported package global,
|
||||
spew.Config. See ConfigState for options documentation.
|
||||
|
||||
+2
@@ -1,4 +1,6 @@
|
||||
//go:build go1.8
|
||||
// +build go1.8
|
||||
|
||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
||||
|
||||
package httpsnoop
|
||||
|
||||
+2
@@ -1,4 +1,6 @@
|
||||
//go:build !go1.8
|
||||
// +build !go1.8
|
||||
|
||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
|
||||
|
||||
package httpsnoop
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+5
-5
@@ -108,9 +108,9 @@ type GUID struct {
|
||||
//
|
||||
// The supplied string may be in any of these formats:
|
||||
//
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
//
|
||||
// The conversion of the supplied string is not case-sensitive.
|
||||
func NewGUID(guid string) *GUID {
|
||||
@@ -216,11 +216,11 @@ func decodeHexChar(c byte) (byte, bool) {
|
||||
|
||||
// String converts the GUID to string form. It will adhere to this pattern:
|
||||
//
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
//
|
||||
// If the GUID is nil, the string representation of an empty GUID is returned:
|
||||
//
|
||||
// {00000000-0000-0000-0000-000000000000}
|
||||
// {00000000-0000-0000-0000-000000000000}
|
||||
func (guid *GUID) String() string {
|
||||
if guid == nil {
|
||||
return emptyGUID
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package oleutil
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package oleutil
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package oleutil
|
||||
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
// This file is here so go get succeeds as without it errors with:
|
||||
// no buildable Go source files in ...
|
||||
//
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package oleutil
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) {
|
||||
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||
values[i] = v
|
||||
case VT_BSTR:
|
||||
v , _ := safeArrayGetElementString(sac.Array, i)
|
||||
v, _ := safeArrayGetElementString(sac.Array, i)
|
||||
values[i] = v
|
||||
case VT_VARIANT:
|
||||
var v VARIANT
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build 386
|
||||
// +build 386
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build amd64
|
||||
// +build amd64
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build arm
|
||||
// +build arm
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows && 386
|
||||
// +build windows,386
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows && amd64
|
||||
// +build windows,amd64
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows && arm
|
||||
// +build windows,arm
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build ppc64le
|
||||
// +build ppc64le
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build s390x
|
||||
// +build s390x
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package ole
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package ole
|
||||
|
||||
+18
-18
@@ -39,35 +39,35 @@ for a protocol buffer variable v:
|
||||
|
||||
- Names are turned from camel_case to CamelCase for export.
|
||||
- There are no methods on v to set fields; just treat
|
||||
them as structure fields.
|
||||
them as structure fields.
|
||||
- There are getters that return a field's value if set,
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
- The zero value for a struct is its correct initialization state.
|
||||
All desired fields must be set before marshaling.
|
||||
All desired fields must be set before marshaling.
|
||||
- A Reset() method will restore a protobuf struct to its zero state.
|
||||
- Non-repeated fields are pointers to the values; nil means unset.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
- Repeated fields are slices.
|
||||
- Helper functions are available to aid the setting of fields.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
- Enums are given type names and maps from names to values.
|
||||
Enum values are prefixed by the enclosing message's name, or by the
|
||||
enum's type name if it is a top-level enum. Enum types have a String
|
||||
method, and a Enum method to assist in message construction.
|
||||
Enum values are prefixed by the enclosing message's name, or by the
|
||||
enum's type name if it is a top-level enum. Enum types have a String
|
||||
method, and a Enum method to assist in message construction.
|
||||
- Nested messages, groups and enums have type names prefixed with the name of
|
||||
the surrounding message type.
|
||||
the surrounding message type.
|
||||
- Extensions are given descriptor names that start with E_,
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
- Oneof field sets are given a single field in their message,
|
||||
with distinguished wrapper types for each possible field value.
|
||||
with distinguished wrapper types for each possible field value.
|
||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
+1
@@ -29,6 +29,7 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//go:build purego || appengine || js
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
|
||||
+1
@@ -26,6 +26,7 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//go:build purego || appengine || js
|
||||
// +build purego appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
|
||||
+1
@@ -29,6 +29,7 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//go:build !purego && !appengine && !js
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
+1
@@ -26,6 +26,7 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//go:build !purego && !appengine && !js
|
||||
// +build !purego,!appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
+8
-6
@@ -2004,12 +2004,14 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
|
||||
|
||||
// makeUnmarshalOneof makes an unmarshaler for oneof fields.
|
||||
// for:
|
||||
// message Msg {
|
||||
// oneof F {
|
||||
// int64 X = 1;
|
||||
// float64 Y = 2;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// message Msg {
|
||||
// oneof F {
|
||||
// int64 X = 1;
|
||||
// float64 Y = 2;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// typ is the type of the concrete entry for a oneof case (e.g. Msg_X).
|
||||
// ityp is the interface type of the oneof field (e.g. isMsg_F).
|
||||
// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64).
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||
// domain with the id returned by os.Getuid.
|
||||
//
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
func NewDCEPerson() (UUID, error) {
|
||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func NewDCEPerson() (UUID, error) {
|
||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||
// domain with the id returned by os.Getgid.
|
||||
//
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
func NewDCEGroup() (UUID, error) {
|
||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
}
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(md5.New(), space, data, 3)
|
||||
// NewHash(md5.New(), space, data, 3)
|
||||
func NewMD5(space UUID, data []byte) UUID {
|
||||
return NewHash(md5.New(), space, data, 3)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func NewMD5(space UUID, data []byte) UUID {
|
||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(sha1.New(), space, data, 5)
|
||||
// NewHash(sha1.New(), space, data, 5)
|
||||
func NewSHA1(space UUID, data []byte) UUID {
|
||||
return NewHash(sha1.New(), space, data, 5)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user