2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  sqlstore  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:48:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-18 02:23:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"go.opentelemetry.io/otel/attribute" 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 20:54:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"go.opentelemetry.io/otel/trace" 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"go.opentelemetry.io/otel/trace/noop" 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-03 22:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"xorm.io/core" 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-10 22:59:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 21:57:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"xorm.io/xorm" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-13 12:11:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/apimachinery/errutil" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/infra/log" 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/infra/tracing" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:48:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/services/sqlstore/migrator" 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/grafana/grafana/pkg/util/retryer" 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  sessionLogger  =  log . New ( "sqlstore.session" )  
						 
					
						
							
								
									
										
										
										
											2023-08-22 18:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  ErrMaximumRetriesReached  =  errutil . Internal ( "sqlstore.max-retries-reached" )  
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  DBSession  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* xorm . Session 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									transactionOpen  bool 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									events           [ ] any 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:51:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  DBTransactionFunc  func ( sess  * DBSession )  error  
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sess  * DBSession )  publishAfterCommit ( msg  any )  {  
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									sess . events  =  append ( sess . events ,  msg ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-28 20:32:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sess  * DBSession )  PublishAfterCommit ( msg  any )  {  
						 
					
						
							
								
									
										
										
										
											2022-06-28 20:32:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sess . events  =  append ( sess . events ,  msg ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 20:54:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  startSessionOrUseExisting ( ctx  context . Context ,  engine  * xorm . Engine ,  beginTran  bool ,  tracer  tracing . Tracer )  ( * DBSession ,  bool ,  trace . Span ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-03-23 20:37:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									value  :=  ctx . Value ( ContextSessionKey { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  sess  * DBSession 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sess ,  ok  :=  value . ( * DBSession ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-18 20:50:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-21 00:32:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ctxLogger  :=  sessionLogger . FromContext ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctxLogger . Debug ( "reusing existing session" ,  "transaction" ,  sess . transactionOpen ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-27 19:55:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sess . Session  =  sess . Session . Context ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is a noop span to simplify later operations. purposefully not using existing context
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  span  :=  noop . NewTracerProvider ( ) . Tracer ( "integrationtests" ) . Start ( ctx ,  "sqlstore.startSessionOrUseExisting" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  sess ,  false ,  span ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tctx ,  span  :=  tracer . Start ( ctx ,  "open session" ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 20:54:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									span . SetAttributes ( attribute . Bool ( "transaction" ,  beginTran ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newSess  :=  & DBSession { Session :  engine . NewSession ( ) ,  transactionOpen :  beginTran } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-18 20:50:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  beginTran  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  newSess . Begin ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  false ,  span ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-18 20:50:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newSess . Session  =  newSess . Session . Context ( tctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-27 19:55:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  newSess ,  true ,  span ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-29 20:55:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// WithDbSession calls the callback with the session in the context (if exists).
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Otherwise it creates a new one that is closed upon completion.
  
						 
					
						
							
								
									
										
										
										
											2023-01-23 21:17:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A session is stored in the context if sqlstore.InTransaction() has been previously called with the same context (and it's not committed/rolledback yet).
  
						 
					
						
							
								
									
										
										
										
											2025-04-03 22:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// In case of retryable errors, callback will be retried at most five times before giving up.
  
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:51:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ss  * SQLStore )  WithDbSession ( ctx  context . Context ,  callback  DBTransactionFunc )  error  {  
						 
					
						
							
								
									
										
										
										
											2022-10-18 02:23:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ss . withDbSession ( ctx ,  ss . engine ,  callback ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-16 18:39:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-03 22:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ss  * SQLStore )  retryOnLocks ( ctx  context . Context ,  callback  DBTransactionFunc ,  sess  * DBSession ,  retry  int ,  dialect  core . Dialect )  func ( )  ( retryer . RetrySignal ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  func ( )  ( retryer . RetrySignal ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										retry ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-18 02:23:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  callback ( sess ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctxLogger  :=  tsclogger . FromContext ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-03 22:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  r ,  ok  :=  dialect . ( xorm . DialectWithRetryableErrors ) ;  ok  &&  r . RetryOnError ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ctxLogger . Info ( "Database locked, sleeping then retrying" ,  "error" ,  err ,  "retry" ,  retry ,  "code" ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// retryer immediately returns the error (if there is one) without checking the response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// therefore we only have to send it if we have reached the maximum retries
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-17 18:57:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  retry  >=  ss . dbCfg . QueryRetries  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  retryer . FuncError ,  ErrMaximumRetriesReached . Errorf ( "retry %d: %w" ,  retry ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  retryer . FuncFailure ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-18 02:23:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  retryer . FuncError ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  retryer . FuncComplete ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-18 02:23:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ss  * SQLStore )  withDbSession ( ctx  context . Context ,  engine  * xorm . Engine ,  callback  DBTransactionFunc )  error  {  
						 
					
						
							
								
									
										
										
										
											2023-01-09 22:41:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sess ,  isNew ,  span ,  err  :=  startSessionOrUseExisting ( ctx ,  engine ,  false ,  ss . tracer ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  span . End ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  tracing . Errorf ( span ,  "start session failed: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isNew  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-06 09:17:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										defer  sess . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 22:02:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 19:12:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retry  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-03 22:26:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  retryer . Retry ( ss . retryOnLocks ( ctx ,  callback ,  sess ,  retry ,  engine . Dialect ( ) ) ,  ss . dbCfg . QueryRetries ,  time . Millisecond * time . Duration ( 10 ) ,  time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sess  * DBSession )  InsertId ( bean  any ,  dialect  migrator . Dialect )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									table  :=  sess . DB ( ) . Mapper . Obj2Table ( getTypeName ( bean ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 20:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  dialect . PreInsertId ( table ,  sess . Session ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 19:01:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 20:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 19:01:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  sess . Session . InsertOne ( bean ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 20:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 19:01:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 20:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  dialect . PostInsertId ( table ,  sess . Session ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 19:01:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 20:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 19:01:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sess  * DBSession )  WithReturningID ( driverName  string ,  query  string ,  args  [ ] any )  ( int64 ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:48:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  id  int64 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-10 22:59:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  driverName  ==  migrator . Postgres  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:48:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										query  =  fmt . Sprintf ( "%s RETURNING id" ,  query ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  :=  sess . SQL ( query ,  args ... ) . Get ( & id ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  id ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-10 22:59:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  driverName  ==  migrator . Spanner  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Only works with INSERT statements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											query  =  fmt . Sprintf ( "%s THEN RETURN id" ,  query ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sqlOrArgs  :=  append ( [ ] any { query } ,  args ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:48:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res ,  err  :=  sess . Exec ( sqlOrArgs ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  id ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										id ,  err  =  res . LastInsertId ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  id ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  id ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-30 23:46:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getTypeName ( bean  any )  ( res  string )  {  
						 
					
						
							
								
									
										
										
										
											2018-06-08 03:54:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t  :=  reflect . TypeOf ( bean ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  t . Kind ( )  ==  reflect . Ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t  =  t . Elem ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  t . Name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}