github.com/altipla-consulting/ravendb-go-client@v0.1.3/document_conventions.go (about) 1 package ravendb 2 3 import ( 4 "reflect" 5 "strings" 6 "sync" 7 "time" 8 "unicode" 9 ) 10 11 var ( 12 // Note: helps find places that in Java code used DocumentConventsion.GetIdentityProperty() 13 // if we add support for that 14 documentConventionsIdentityPropertyName = "ID" 15 ) 16 17 type DocumentIDGeneratorFunc func(dbName string, entity interface{}) (string, error) 18 19 // DocumentConventions describes document conventions 20 type DocumentConventions struct { 21 frozen bool 22 originalConfiguration *ClientConfiguration 23 24 MaxNumberOfRequestsPerSession int 25 // timeout for wait to server 26 Timeout time.Duration 27 UseOptimisticConcurrency bool 28 // JsonDefaultMethod = DocumentConventions.json_default 29 MaxLengthOfQueryUsingGetURL int 30 IdentityPartsSeparator string 31 disableTopologyUpdates bool 32 // If set to 'true' then it will return an error when any query is performed (in session) 33 // without explicit page size set 34 RaiseIfQueryPageSizeIsNotSet bool // TODO: rename to ErrorIfQueryPageSizeIsNotSet 35 36 documentIDGenerator DocumentIDGeneratorFunc 37 38 // allows overriding entity -> collection name logic 39 FindCollectionName func(interface{}) string 40 41 ReadBalanceBehavior ReadBalanceBehavior 42 transformClassCollectionNameToDocumentIDPrefix func(string) string 43 44 // if true, will return error if page size is not set 45 ErrorIfQueryPageSizeIsNotSet bool 46 47 maxHttpCacheSize int 48 49 // a pointer to silence go vet when copying DocumentConventions wholesale 50 mu *sync.Mutex 51 } 52 53 // Note: Java has it as frozen global variable (possibly for perf) but Go 54 // has no notion of frozen objects so for safety we create new object 55 // (avoids accidental modification of shared, global state) 56 // TODO: replace with direct calls to NewDocumentConventions() 57 func getDefaultConventions() *DocumentConventions { 58 return NewDocumentConventions() 59 } 60 61 // NewDocumentConventions creates DocumentConventions with default values 62 func NewDocumentConventions() *DocumentConventions { 63 return &DocumentConventions{ 64 ReadBalanceBehavior: ReadBalanceBehaviorNone, 65 MaxLengthOfQueryUsingGetURL: 1024 + 512, 66 IdentityPartsSeparator: "/", 67 disableTopologyUpdates: false, 68 RaiseIfQueryPageSizeIsNotSet: false, 69 transformClassCollectionNameToDocumentIDPrefix: getDefaultTransformCollectionNameToDocumentIdPrefix, 70 MaxNumberOfRequestsPerSession: 32, 71 maxHttpCacheSize: 128 * 1024 * 1024, 72 mu: &sync.Mutex{}, 73 } 74 } 75 76 func (c *DocumentConventions) getMaxHttpCacheSize() int { 77 return c.maxHttpCacheSize 78 } 79 80 func (c *DocumentConventions) Freeze() { 81 c.frozen = true 82 } 83 84 // GetCollectionNameDefault is a default way of 85 func GetCollectionNameDefault(entityOrType interface{}) string { 86 name := getShortTypeNameForEntityOrType(entityOrType) 87 return ToPlural(name) 88 } 89 90 func (c *DocumentConventions) getCollectionName(entityOrType interface{}) string { 91 if c.FindCollectionName != nil { 92 return c.FindCollectionName(entityOrType) 93 } 94 return GetCollectionNameDefault(entityOrType) 95 } 96 97 func getCollectionNameForTypeOrEntity(entityOrType interface{}) string { 98 name := getShortTypeNameForEntityOrType(entityOrType) 99 return ToPlural(name) 100 } 101 102 func (c *DocumentConventions) UpdateFrom(configuration *ClientConfiguration) { 103 if configuration == nil { 104 return 105 } 106 107 c.mu.Lock() 108 defer c.mu.Unlock() 109 110 if configuration.IsDisabled && c.originalConfiguration == nil { 111 // nothing to do 112 return 113 } 114 115 if configuration.IsDisabled && c.originalConfiguration != nil { 116 // need to revert to original values 117 c.MaxNumberOfRequestsPerSession = c.originalConfiguration.MaxNumberOfRequestsPerSession 118 c.ReadBalanceBehavior = c.originalConfiguration.ReadBalanceBehavior 119 120 c.originalConfiguration = nil 121 return 122 } 123 124 if c.originalConfiguration == nil { 125 c.originalConfiguration = &ClientConfiguration{} 126 c.originalConfiguration.Etag = -1 127 c.originalConfiguration.MaxNumberOfRequestsPerSession = c.MaxNumberOfRequestsPerSession 128 c.originalConfiguration.ReadBalanceBehavior = c.ReadBalanceBehavior 129 } 130 131 c.MaxNumberOfRequestsPerSession = firstNonZero(configuration.MaxNumberOfRequestsPerSession, c.originalConfiguration.MaxNumberOfRequestsPerSession) 132 133 c.ReadBalanceBehavior = firstNonEmptyString(configuration.ReadBalanceBehavior, c.originalConfiguration.ReadBalanceBehavior) 134 } 135 136 func getDefaultTransformCollectionNameToDocumentIdPrefix(collectionName string) string { 137 upperCount := 0 138 for _, c := range collectionName { 139 if unicode.IsUpper(c) { 140 upperCount++ 141 142 // multiple capital letters, so probably something that we want to preserve caps on. 143 if upperCount > 1 { 144 return collectionName 145 } 146 } 147 } 148 if upperCount == 1 { 149 return strings.ToLower(collectionName) 150 } 151 // upperCount must be 0 152 return collectionName 153 } 154 155 func (c *DocumentConventions) Clone() *DocumentConventions { 156 res := *c 157 // mutex carries its locking state so we need to re-initialize it 158 res.mu = &sync.Mutex{} 159 return &res 160 } 161 162 func (c *DocumentConventions) getGoTypeName(entity interface{}) string { 163 return getFullTypeName(entity) 164 } 165 166 // returns "" if no identity property 167 func (c *DocumentConventions) GetIdentityProperty(clazz reflect.Type) string { 168 return getIdentityProperty(clazz) 169 } 170 171 func (c *DocumentConventions) GetDocumentIDGenerator() DocumentIDGeneratorFunc { 172 return c.documentIDGenerator 173 } 174 175 func (c *DocumentConventions) SetDocumentIDGenerator(documentIDGenerator DocumentIDGeneratorFunc) { 176 c.documentIDGenerator = documentIDGenerator 177 } 178 179 // Generates the document id. 180 func (c *DocumentConventions) GenerateDocumentID(databaseName string, entity interface{}) (string, error) { 181 return c.documentIDGenerator(databaseName, entity) 182 } 183 184 func (c *DocumentConventions) IsDisableTopologyUpdates() bool { 185 return c.disableTopologyUpdates 186 } 187 188 func (c *DocumentConventions) SetDisableTopologyUpdates(disable bool) { 189 c.disableTopologyUpdates = disable 190 } 191 192 func (c *DocumentConventions) GetIdentityPartsSeparator() string { 193 return c.IdentityPartsSeparator 194 } 195 196 func (c *DocumentConventions) GetTransformClassCollectionNameToDocumentIdPrefix() func(string) string { 197 return c.transformClassCollectionNameToDocumentIDPrefix 198 } 199 200 func (c *DocumentConventions) TryConvertValueForQuery(fieldName string, value interface{}, forRange bool, stringValue *string) bool { 201 // TODO: implement me 202 // Tested by CustomSerializationTest 203 /* 204 for (Tuple<Class, IValueForQueryConverter<Object>> queryValueConverter : _listOfQueryValueConverters) { 205 if (!queryValueConverter.first.isInstance(value)) { 206 continue; 207 } 208 209 return queryValueConverter.second.tryConvertValueForQuery(fieldName, value, forRange, stringValue); 210 } 211 */ 212 *stringValue = "" 213 return false 214 }