| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | package sql | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"database/sql" | 
					
						
							|  |  |  | 	"embed" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"text/template" | 
					
						
							| 
									
										
										
										
											2025-01-09 04:08:10 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 04:08:10 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/apimachinery/utils" | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/storage/unified/resource" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Templates setup.
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	//go:embed data/*.sql
 | 
					
						
							|  |  |  | 	sqlTemplatesFS embed.FS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sqlTemplates = template.Must(template.New("sql").ParseFS(sqlTemplatesFS, `data/*.sql`)) | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mustTemplate(filename string) *template.Template { | 
					
						
							|  |  |  | 	if t := sqlTemplates.Lookup(filename); t != nil { | 
					
						
							|  |  |  | 		return t | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	panic(fmt.Sprintf("template file not found: %s", filename)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Templates.
 | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2025-03-28 01:34:37 +08:00
										 |  |  | 	sqlResourceDelete              = mustTemplate("resource_delete.sql") | 
					
						
							|  |  |  | 	sqlResourceInsert              = mustTemplate("resource_insert.sql") | 
					
						
							|  |  |  | 	sqlResourceUpdate              = mustTemplate("resource_update.sql") | 
					
						
							|  |  |  | 	sqlResourceRead                = mustTemplate("resource_read.sql") | 
					
						
							|  |  |  | 	sqlResourceStats               = mustTemplate("resource_stats.sql") | 
					
						
							|  |  |  | 	sqlResourceList                = mustTemplate("resource_list.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryList         = mustTemplate("resource_history_list.sql") | 
					
						
							|  |  |  | 	sqlResourceUpdateRV            = mustTemplate("resource_update_rv.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryRead         = mustTemplate("resource_history_read.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryReadLatestRV = mustTemplate("resource_history_read_latest_rv.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryUpdateRV     = mustTemplate("resource_history_update_rv.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryInsert       = mustTemplate("resource_history_insert.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryPoll         = mustTemplate("resource_history_poll.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryGet          = mustTemplate("resource_history_get.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryDelete       = mustTemplate("resource_history_delete.sql") | 
					
						
							|  |  |  | 	sqlResourceHistoryPrune        = mustTemplate("resource_history_prune.sql") | 
					
						
							|  |  |  | 	sqlResourceInsertFromHistory   = mustTemplate("resource_insert_from_history.sql") | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// sqlResourceLabelsInsert = mustTemplate("resource_labels_insert.sql")
 | 
					
						
							|  |  |  | 	sqlResourceVersionGet    = mustTemplate("resource_version_get.sql") | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | 	sqlResourceVersionUpdate = mustTemplate("resource_version_update.sql") | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	sqlResourceVersionInsert = mustTemplate("resource_version_insert.sql") | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | 	sqlResourceVersionList   = mustTemplate("resource_version_list.sql") | 
					
						
							| 
									
										
										
										
											2025-01-09 04:08:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sqlResourceBlobInsert = mustTemplate("resource_blob_insert.sql") | 
					
						
							|  |  |  | 	sqlResourceBlobQuery  = mustTemplate("resource_blob_query.sql") | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TxOptions.
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	ReadCommitted = &sql.TxOptions{ | 
					
						
							|  |  |  | 		Isolation: sql.LevelReadCommitted, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ReadCommittedRO = &sql.TxOptions{ | 
					
						
							|  |  |  | 		Isolation: sql.LevelReadCommitted, | 
					
						
							|  |  |  | 		ReadOnly:  true, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-07 02:58:07 +08:00
										 |  |  | 	RepeatableRead = &sql.TxOptions{ | 
					
						
							|  |  |  | 		Isolation: sql.LevelRepeatableRead, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	GUID       string | 
					
						
							|  |  |  | 	WriteEvent resource.WriteEvent | 
					
						
							| 
									
										
										
										
											2025-04-02 01:38:23 +08:00
										 |  |  | 	Generation int64 | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | 	Folder     string | 
					
						
							| 
									
										
										
										
											2025-01-21 17:15:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Useful when batch writing
 | 
					
						
							|  |  |  | 	ResourceVersion int64 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-12 01:57:46 +08:00
										 |  |  | type sqlResourceInsertFromHistoryRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Key *resource.ResourceKey | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceInsertFromHistoryRequest) Validate() error { | 
					
						
							|  |  |  | 	if r.Key == nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing key") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-04 01:20:27 +08:00
										 |  |  | type sqlStatsRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-12-05 18:58:13 +08:00
										 |  |  | 	Namespace string | 
					
						
							| 
									
										
										
										
											2025-01-21 17:15:08 +08:00
										 |  |  | 	Group     string | 
					
						
							|  |  |  | 	Resource  string | 
					
						
							| 
									
										
										
										
											2024-12-11 02:37:37 +08:00
										 |  |  | 	Folder    string | 
					
						
							| 
									
										
										
										
											2024-12-05 18:58:13 +08:00
										 |  |  | 	MinCount  int | 
					
						
							| 
									
										
										
										
											2024-12-04 01:20:27 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlStatsRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2024-12-11 02:37:37 +08:00
										 |  |  | 	if r.Folder != "" && r.Namespace == "" { | 
					
						
							|  |  |  | 		return fmt.Errorf("folder constraint requires a namespace") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2024-12-04 01:20:27 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | type historyPollResponse struct { | 
					
						
							|  |  |  | 	Key             resource.ResourceKey | 
					
						
							| 
									
										
										
										
											2025-04-17 18:58:58 +08:00
										 |  |  | 	GUID            string | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	ResourceVersion int64 | 
					
						
							| 
									
										
										
										
											2024-10-07 16:01:53 +08:00
										 |  |  | 	PreviousRV      *int64 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	Value           []byte | 
					
						
							|  |  |  | 	Action          int | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | 	Folder          string | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *historyPollResponse) Results() (*historyPollResponse, error) { | 
					
						
							|  |  |  | 	return r, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | type groupResourceRV map[string]map[string]int64 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | type sqlResourceHistoryPollRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | 	Resource             string | 
					
						
							|  |  |  | 	Group                string | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	SinceResourceVersion int64 | 
					
						
							|  |  |  | 	Response             *historyPollResponse | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | func (r *sqlResourceHistoryPollRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | func (r *sqlResourceHistoryPollRequest) Results() (*historyPollResponse, error) { | 
					
						
							| 
									
										
										
										
											2024-10-07 16:01:53 +08:00
										 |  |  | 	prevRV := r.Response.PreviousRV | 
					
						
							|  |  |  | 	if prevRV == nil { | 
					
						
							| 
									
										
										
										
											2024-11-28 21:28:55 +08:00
										 |  |  | 		prevRV = new(int64) | 
					
						
							| 
									
										
										
										
											2024-10-07 16:01:53 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | 	return &historyPollResponse{ | 
					
						
							|  |  |  | 		Key: resource.ResourceKey{ | 
					
						
							|  |  |  | 			Namespace: r.Response.Key.Namespace, | 
					
						
							|  |  |  | 			Group:     r.Response.Key.Group, | 
					
						
							|  |  |  | 			Resource:  r.Response.Key.Resource, | 
					
						
							|  |  |  | 			Name:      r.Response.Key.Name, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | 		Folder:          r.Response.Folder, | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | 		ResourceVersion: r.Response.ResourceVersion, | 
					
						
							| 
									
										
										
										
											2024-10-07 16:01:53 +08:00
										 |  |  | 		PreviousRV:      prevRV, | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | 		Value:           r.Response.Value, | 
					
						
							|  |  |  | 		Action:          r.Response.Action, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | // sqlResourceReadRequest can be used to retrieve a row fromthe "resource" tables.
 | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | func NewReadResponse() *resource.BackendReadResponse { | 
					
						
							|  |  |  | 	return &resource.BackendReadResponse{ | 
					
						
							|  |  |  | 		Key: &resource.ResourceKey{}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceReadRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | 	Request  *resource.ReadRequest | 
					
						
							|  |  |  | 	Response *resource.BackendReadResponse | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | func (r *sqlResourceReadRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | func (r *sqlResourceReadRequest) Results() (*resource.BackendReadResponse, error) { | 
					
						
							|  |  |  | 	return r.Response, nil | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | // List
 | 
					
						
							|  |  |  | type sqlResourceListRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-31 17:05:59 +08:00
										 |  |  | 	Request *resource.ListRequest | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceListRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-28 01:34:37 +08:00
										 |  |  | type historyReadRequest struct { | 
					
						
							|  |  |  | 	Key             *resource.ResourceKey | 
					
						
							|  |  |  | 	ResourceVersion int64 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceHistoryReadRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Request  *historyReadRequest | 
					
						
							|  |  |  | 	Response *resource.BackendReadResponse | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceHistoryReadRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceHistoryReadRequest) Results() (*resource.BackendReadResponse, error) { | 
					
						
							|  |  |  | 	return r.Response, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type historyReadLatestRVRequest struct { | 
					
						
							|  |  |  | 	Key       *resource.ResourceKey | 
					
						
							|  |  |  | 	EventType resource.WatchEvent_Type | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceHistoryReadLatestRVRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Request  *historyReadLatestRVRequest | 
					
						
							|  |  |  | 	Response *resourceHistoryReadLatestRVResponse | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceHistoryReadLatestRVRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceHistoryReadLatestRVRequest) Results() (*resourceHistoryReadLatestRVResponse, error) { | 
					
						
							|  |  |  | 	return r.Response, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type resourceHistoryReadLatestRVResponse struct { | 
					
						
							|  |  |  | 	ResourceVersion int64 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *resourceHistoryReadLatestRVResponse) Results() (*resourceHistoryReadLatestRVResponse, error) { | 
					
						
							|  |  |  | 	return r, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | type historyListRequest struct { | 
					
						
							|  |  |  | 	ResourceVersion, Limit, Offset int64 | 
					
						
							| 
									
										
										
										
											2024-11-12 19:52:04 +08:00
										 |  |  | 	Folder                         string | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	Options                        *resource.ListOptions | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type sqlResourceHistoryListRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	Request  *historyListRequest | 
					
						
							|  |  |  | 	Response *resource.ResourceWrapper | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceHistoryListRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-23 01:08:30 +08:00
										 |  |  | func (r sqlResourceHistoryListRequest) Results() (*resource.ResourceWrapper, error) { | 
					
						
							|  |  |  | 	// sqlResourceHistoryListRequest is a set-returning query. As such, it
 | 
					
						
							|  |  |  | 	// should not return its *Response, since that will be overwritten in the
 | 
					
						
							|  |  |  | 	// next call to `Scan`, so it needs to return a copy of it. Note, though,
 | 
					
						
							|  |  |  | 	// that it is safe to return the same `Response.Value` since `Scan`
 | 
					
						
							|  |  |  | 	// allocates a new slice of bytes each time.
 | 
					
						
							|  |  |  | 	return &resource.ResourceWrapper{ | 
					
						
							|  |  |  | 		ResourceVersion: r.Response.ResourceVersion, | 
					
						
							|  |  |  | 		Value:           r.Response.Value, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-17 20:54:25 +08:00
										 |  |  | type sqlResourceHistoryDeleteRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	GUID string | 
					
						
							| 
									
										
										
										
											2025-01-21 17:15:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Namespace string | 
					
						
							|  |  |  | 	Group     string | 
					
						
							|  |  |  | 	Resource  string | 
					
						
							| 
									
										
										
										
											2025-01-17 20:54:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *sqlResourceHistoryDeleteRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2025-01-21 17:15:08 +08:00
										 |  |  | 	if r.Namespace == "" { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing namespace") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.GUID == "" { | 
					
						
							|  |  |  | 		if r.Group == "" { | 
					
						
							|  |  |  | 			return fmt.Errorf("missing group") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if r.Resource == "" { | 
					
						
							|  |  |  | 			return fmt.Errorf("missing resource") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2025-01-17 20:54:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlGetHistoryRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2025-03-22 00:35:32 +08:00
										 |  |  | 	Key           *resource.ResourceKey | 
					
						
							|  |  |  | 	Trash         bool  // only deleted items
 | 
					
						
							|  |  |  | 	StartRV       int64 // from NextPageToken
 | 
					
						
							|  |  |  | 	MinRV         int64 // minimum resource version for NotOlderThan
 | 
					
						
							|  |  |  | 	ExactRV       int64 // exact resource version for Exact
 | 
					
						
							|  |  |  | 	SortAscending bool  // if true, sort by resource_version ASC, otherwise DESC
 | 
					
						
							| 
									
										
										
										
											2025-01-17 20:54:25 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlGetHistoryRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-17 18:36:38 +08:00
										 |  |  | // prune resource history
 | 
					
						
							|  |  |  | type sqlPruneHistoryRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2025-04-02 01:38:23 +08:00
										 |  |  | 	Key                   *resource.ResourceKey | 
					
						
							|  |  |  | 	PartitionByGeneration bool // include generation in the partition
 | 
					
						
							|  |  |  | 	HistoryLimit          int64 | 
					
						
							| 
									
										
										
										
											2025-03-17 18:36:38 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *sqlPruneHistoryRequest) Validate() error { | 
					
						
							|  |  |  | 	if r.HistoryLimit <= 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("history limit must be greater than zero") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.Key == nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing key") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.Key.Namespace == "" { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing namespace") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.Key.Group == "" { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing group") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r.Key.Resource == "" { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing resource") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 04:08:10 +08:00
										 |  |  | type sqlResourceBlobInsertRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Now         time.Time | 
					
						
							|  |  |  | 	Info        *utils.BlobInfo | 
					
						
							|  |  |  | 	Key         *resource.ResourceKey | 
					
						
							|  |  |  | 	Value       []byte | 
					
						
							|  |  |  | 	ContentType string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceBlobInsertRequest) Validate() error { | 
					
						
							|  |  |  | 	if len(r.Value) < 1 { | 
					
						
							|  |  |  | 		return fmt.Errorf("missing body") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceBlobQueryRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Key *resource.ResourceKey | 
					
						
							|  |  |  | 	UID string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceBlobQueryRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | // update RV
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceUpdateRVRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2025-03-13 16:24:12 +08:00
										 |  |  | 	GUIDToRV map[string]int64 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r sqlResourceUpdateRVRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // resource_version table requests.
 | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | type resourceVersionResponse struct { | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	ResourceVersion int64 | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | 	CurrentEpoch    int64 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *resourceVersionResponse) Results() (*resourceVersionResponse, error) { | 
					
						
							|  |  |  | 	return r, nil | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | type groupResourceVersion struct { | 
					
						
							|  |  |  | 	Group, Resource string | 
					
						
							|  |  |  | 	ResourceVersion int64 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | type sqlResourceVersionUpsertRequest struct { | 
					
						
							|  |  |  | 	sqltemplate.SQLTemplate | 
					
						
							|  |  |  | 	Group, Resource string | 
					
						
							|  |  |  | 	ResourceVersion int64 | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | func (r sqlResourceVersionUpsertRequest) Validate() error { | 
					
						
							|  |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceVersionGetRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	Group, Resource string | 
					
						
							| 
									
										
										
										
											2024-07-26 19:56:24 +08:00
										 |  |  | 	ReadOnly        bool | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | 	Response        *resourceVersionResponse | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | func (r sqlResourceVersionGetRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2024-07-18 23:03:18 +08:00
										 |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-10-11 17:11:33 +08:00
										 |  |  | func (r sqlResourceVersionGetRequest) Results() (*resourceVersionResponse, error) { | 
					
						
							|  |  |  | 	return &resourceVersionResponse{ | 
					
						
							|  |  |  | 		ResourceVersion: r.Response.ResourceVersion, | 
					
						
							|  |  |  | 		CurrentEpoch:    r.Response.CurrentEpoch, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type sqlResourceVersionListRequest struct { | 
					
						
							| 
									
										
										
										
											2024-08-16 20:12:37 +08:00
										 |  |  | 	sqltemplate.SQLTemplate | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | 	*groupResourceVersion | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | func (r *sqlResourceVersionListRequest) Validate() error { | 
					
						
							| 
									
										
										
										
											2024-07-22 21:07:12 +08:00
										 |  |  | 	return nil // TODO
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-20 20:29:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (r *sqlResourceVersionListRequest) Results() (*groupResourceVersion, error) { | 
					
						
							|  |  |  | 	x := *r.groupResourceVersion | 
					
						
							|  |  |  | 	return &x, nil | 
					
						
							|  |  |  | } |