mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:58:35 +00:00 
			
		
		
		
	Add a storage layer for attachments (#11387)
* Add a storage layer for attachments * Fix some bug * fix test * Fix copyright head and lint * Fix bug * Add setting for minio and flags for migrate-storage * Add documents * fix lint * Add test for minio store type on attachments * fix test * fix test * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Add warning when storage migrated successfully * Fix drone * fix test * rebase * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * refactor the codes * add trace * Fix test * remove log on xorm * Fi download bug * Add a storage layer for attachments * Add setting for minio and flags for migrate-storage * fix lint * Add test for minio store type on attachments * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Fix drone * fix test * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * refactor the codes * add trace * Fix test * Add URL function to serve attachments directly from S3/Minio * Add ability to enable/disable redirection in attachment configuration * Fix typo * Add a storage layer for attachments * Add setting for minio and flags for migrate-storage * fix lint * Add test for minio store type on attachments * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Fix drone * fix test * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * don't change unrelated files * Fix lint * Fix build * update go.mod and go.sum * Use github.com/minio/minio-go/v6 * Remove unused function * Upgrade minio to v7 and some other improvements * fix lint * Fix go mod Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: Tyler <tystuyfzand@gmail.com>
This commit is contained in:
		
							
								
								
									
										211
									
								
								vendor/github.com/json-iterator/go/reflect_struct_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								vendor/github.com/json-iterator/go/reflect_struct_encoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | ||||
| package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { | ||||
| 	type bindingTo struct { | ||||
| 		binding *Binding | ||||
| 		toName  string | ||||
| 		ignored bool | ||||
| 	} | ||||
| 	orderedBindings := []*bindingTo{} | ||||
| 	structDescriptor := describeStruct(ctx, typ) | ||||
| 	for _, binding := range structDescriptor.Fields { | ||||
| 		for _, toName := range binding.ToNames { | ||||
| 			new := &bindingTo{ | ||||
| 				binding: binding, | ||||
| 				toName:  toName, | ||||
| 			} | ||||
| 			for _, old := range orderedBindings { | ||||
| 				if old.toName != toName { | ||||
| 					continue | ||||
| 				} | ||||
| 				old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) | ||||
| 			} | ||||
| 			orderedBindings = append(orderedBindings, new) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(orderedBindings) == 0 { | ||||
| 		return &emptyStructEncoder{} | ||||
| 	} | ||||
| 	finalOrderedFields := []structFieldTo{} | ||||
| 	for _, bindingTo := range orderedBindings { | ||||
| 		if !bindingTo.ignored { | ||||
| 			finalOrderedFields = append(finalOrderedFields, structFieldTo{ | ||||
| 				encoder: bindingTo.binding.Encoder.(*structFieldEncoder), | ||||
| 				toName:  bindingTo.toName, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 	return &structEncoder{typ, finalOrderedFields} | ||||
| } | ||||
|  | ||||
| func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { | ||||
| 	encoder := createEncoderOfNative(ctx, typ) | ||||
| 	if encoder != nil { | ||||
| 		return encoder | ||||
| 	} | ||||
| 	kind := typ.Kind() | ||||
| 	switch kind { | ||||
| 	case reflect.Interface: | ||||
| 		return &dynamicEncoder{typ} | ||||
| 	case reflect.Struct: | ||||
| 		return &structEncoder{typ: typ} | ||||
| 	case reflect.Array: | ||||
| 		return &arrayEncoder{} | ||||
| 	case reflect.Slice: | ||||
| 		return &sliceEncoder{} | ||||
| 	case reflect.Map: | ||||
| 		return encoderOfMap(ctx, typ) | ||||
| 	case reflect.Ptr: | ||||
| 		return &OptionalEncoder{} | ||||
| 	default: | ||||
| 		return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { | ||||
| 	newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" | ||||
| 	oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" | ||||
| 	if newTagged { | ||||
| 		if oldTagged { | ||||
| 			if len(old.levels) > len(new.levels) { | ||||
| 				return true, false | ||||
| 			} else if len(new.levels) > len(old.levels) { | ||||
| 				return false, true | ||||
| 			} else { | ||||
| 				return true, true | ||||
| 			} | ||||
| 		} else { | ||||
| 			return true, false | ||||
| 		} | ||||
| 	} else { | ||||
| 		if oldTagged { | ||||
| 			return true, false | ||||
| 		} | ||||
| 		if len(old.levels) > len(new.levels) { | ||||
| 			return true, false | ||||
| 		} else if len(new.levels) > len(old.levels) { | ||||
| 			return false, true | ||||
| 		} else { | ||||
| 			return true, true | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type structFieldEncoder struct { | ||||
| 	field        reflect2.StructField | ||||
| 	fieldEncoder ValEncoder | ||||
| 	omitempty    bool | ||||
| } | ||||
|  | ||||
| func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	fieldPtr := encoder.field.UnsafeGet(ptr) | ||||
| 	encoder.fieldEncoder.Encode(fieldPtr, stream) | ||||
| 	if stream.Error != nil && stream.Error != io.EOF { | ||||
| 		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	fieldPtr := encoder.field.UnsafeGet(ptr) | ||||
| 	return encoder.fieldEncoder.IsEmpty(fieldPtr) | ||||
| } | ||||
|  | ||||
| func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { | ||||
| 	isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) | ||||
| 	if !converted { | ||||
| 		return false | ||||
| 	} | ||||
| 	fieldPtr := encoder.field.UnsafeGet(ptr) | ||||
| 	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) | ||||
| } | ||||
|  | ||||
| type IsEmbeddedPtrNil interface { | ||||
| 	IsEmbeddedPtrNil(ptr unsafe.Pointer) bool | ||||
| } | ||||
|  | ||||
| type structEncoder struct { | ||||
| 	typ    reflect2.Type | ||||
| 	fields []structFieldTo | ||||
| } | ||||
|  | ||||
| type structFieldTo struct { | ||||
| 	encoder *structFieldEncoder | ||||
| 	toName  string | ||||
| } | ||||
|  | ||||
| func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	stream.WriteObjectStart() | ||||
| 	isNotFirst := false | ||||
| 	for _, field := range encoder.fields { | ||||
| 		if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { | ||||
| 			continue | ||||
| 		} | ||||
| 		if field.encoder.IsEmbeddedPtrNil(ptr) { | ||||
| 			continue | ||||
| 		} | ||||
| 		if isNotFirst { | ||||
| 			stream.WriteMore() | ||||
| 		} | ||||
| 		stream.WriteObjectField(field.toName) | ||||
| 		field.encoder.Encode(ptr, stream) | ||||
| 		isNotFirst = true | ||||
| 	} | ||||
| 	stream.WriteObjectEnd() | ||||
| 	if stream.Error != nil && stream.Error != io.EOF { | ||||
| 		stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type emptyStructEncoder struct { | ||||
| } | ||||
|  | ||||
| func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	stream.WriteEmptyObject() | ||||
| } | ||||
|  | ||||
| func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type stringModeNumberEncoder struct { | ||||
| 	elemEncoder ValEncoder | ||||
| } | ||||
|  | ||||
| func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	stream.writeByte('"') | ||||
| 	encoder.elemEncoder.Encode(ptr, stream) | ||||
| 	stream.writeByte('"') | ||||
| } | ||||
|  | ||||
| func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return encoder.elemEncoder.IsEmpty(ptr) | ||||
| } | ||||
|  | ||||
| type stringModeStringEncoder struct { | ||||
| 	elemEncoder ValEncoder | ||||
| 	cfg         *frozenConfig | ||||
| } | ||||
|  | ||||
| func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	tempStream := encoder.cfg.BorrowStream(nil) | ||||
| 	tempStream.Attachment = stream.Attachment | ||||
| 	defer encoder.cfg.ReturnStream(tempStream) | ||||
| 	encoder.elemEncoder.Encode(ptr, tempStream) | ||||
| 	stream.WriteString(string(tempStream.Buffer())) | ||||
| } | ||||
|  | ||||
| func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return encoder.elemEncoder.IsEmpty(ptr) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user