github.com/team-ide/go-dialect@v1.9.20/worker/data_source_text.go (about) 1 package worker 2 3 import ( 4 "bufio" 5 "errors" 6 "fmt" 7 "github.com/team-ide/go-dialect/dialect" 8 "io" 9 "os" 10 "strings" 11 ) 12 13 func NewDataSourceText(param *DataSourceParam) (res DataSource) { 14 res = &dataSourceText{ 15 DataSourceParam: param, 16 } 17 return 18 } 19 20 type dataSourceText struct { 21 *DataSourceParam 22 saveFile *os.File 23 isStop bool 24 headerWritten bool 25 } 26 27 func (this_ *dataSourceText) Stop() { 28 this_.isStop = true 29 } 30 31 func (this_ *dataSourceText) ReadStart() (err error) { 32 return 33 } 34 func (this_ *dataSourceText) ReadEnd() (err error) { 35 return 36 } 37 func (this_ *dataSourceText) Read(columnList []*dialect.ColumnModel, onRead func(data *DataSourceData) (err error)) (err error) { 38 defer func() { 39 if e := recover(); e != nil { 40 err = errors.New(fmt.Sprint(e)) 41 } 42 }() 43 if this_.Path == "" { 44 err = errors.New("文件地址不能为空") 45 return 46 } 47 f, err := os.Open(this_.Path) 48 if err != nil { 49 return 50 } 51 buf := bufio.NewReader(f) 52 var line string 53 var rowInfo string 54 separator := this_.GetTextSeparator() 55 columnLength := len(columnList) 56 if columnLength == 0 { 57 err = errors.New("column is null") 58 return 59 } 60 for { 61 if this_.isStop { 62 return 63 } 64 line, err = buf.ReadString('\n') 65 if line != "" { 66 if rowInfo == "" { 67 rowInfo = line 68 } else { 69 rowInfo += line 70 } 71 72 ss := strings.Split(strings.TrimSpace(rowInfo), separator) 73 if len(ss) > columnLength { 74 err = errors.New("row [" + rowInfo + "] can not to column names [" + strings.Join(GetColumnNames(columnList), ",") + "]") 75 return 76 } 77 if len(ss) == columnLength { 78 rowInfo = strings.TrimSpace(rowInfo) 79 if rowInfo != "" { 80 rowInfo = strings.ReplaceAll(rowInfo, this_.GetLinefeed(), "\n") 81 err = readRow(this_.Dia, rowInfo, separator, columnList, onRead) 82 if err != nil { 83 return 84 } 85 } 86 rowInfo = "" 87 } 88 } 89 if err != nil { 90 if err == io.EOF { //读取结束,会报EOF 91 err = nil 92 } 93 break 94 } 95 } 96 if err != nil { 97 return 98 } 99 rowInfo = strings.TrimSpace(rowInfo) 100 if rowInfo != "" { 101 err = readRow(this_.Dia, rowInfo, separator, columnList, onRead) 102 if err != nil { 103 return 104 } 105 } 106 return 107 } 108 109 func GetColumnNames(columnList []*dialect.ColumnModel) (columnNames []string) { 110 for _, column := range columnList { 111 columnNames = append(columnNames, column.ColumnName) 112 } 113 return 114 } 115 116 func readRow(dia dialect.Dialect, rowInfo string, separator string, columnList []*dialect.ColumnModel, onRead func(data *DataSourceData) (err error)) (err error) { 117 calls := strings.Split(rowInfo, separator) 118 data := make(map[string]interface{}) 119 if len(calls) != len(columnList) { 120 err = errors.New("row [" + rowInfo + "] can not to column names [" + strings.Join(GetColumnNames(columnList), ",") + "]") 121 return 122 } 123 for i, column := range columnList { 124 v := calls[i] 125 if !column.ColumnNotNull && v == "" { 126 continue 127 } 128 var info *dialect.ColumnTypeInfo 129 info, err = dia.GetColumnTypeInfo(column) 130 if err != nil { 131 return 132 } 133 if info.IsDateTime || info.IsNumber { 134 if v == "" { 135 continue 136 } 137 } 138 139 data[column.ColumnName] = v 140 } 141 err = onRead(&DataSourceData{ 142 HasData: true, 143 Data: data, 144 }) 145 return 146 } 147 148 func (this_ *dataSourceText) WriteStart() (err error) { 149 150 if this_.Path == "" { 151 err = errors.New("文件地址不能为空") 152 return 153 } 154 155 this_.saveFile, err = os.Create(this_.Path) 156 if err != nil { 157 return 158 } 159 return 160 } 161 func (this_ *dataSourceText) WriteEnd() (err error) { 162 if this_.saveFile != nil { 163 err = this_.saveFile.Close() 164 return 165 } 166 return 167 } 168 169 func (this_ *dataSourceText) WriteHeader(columnList []*dialect.ColumnModel) (err error) { 170 if this_.headerWritten { 171 return 172 } 173 this_.headerWritten = true 174 175 if this_.saveFile == nil { 176 err = this_.WriteStart() 177 if err != nil { 178 return 179 } 180 } 181 182 if this_.isStop { 183 return 184 } 185 186 var valueList []string 187 for _, column := range columnList { 188 str := column.ColumnName 189 str = strings.ReplaceAll(str, "\r\n", this_.GetLinefeed()) 190 str = strings.ReplaceAll(str, "\n", this_.GetLinefeed()) 191 str = strings.ReplaceAll(str, "\r", this_.GetLinefeed()) 192 valueList = append(valueList, str) 193 } 194 195 _, err = this_.saveFile.WriteString(strings.Join(valueList, this_.GetTextSeparator()) + "\n") 196 if err != nil { 197 return 198 } 199 return 200 } 201 202 func (this_ *dataSourceText) Write(data *DataSourceData) (err error) { 203 defer func() { 204 if e := recover(); e != nil { 205 err = errors.New(fmt.Sprint(e)) 206 } 207 }() 208 if this_.saveFile == nil { 209 err = this_.WriteStart() 210 if err != nil { 211 return 212 } 213 } 214 215 if this_.isStop { 216 return 217 } 218 columnList := data.ColumnList 219 if data.Data == nil || columnList == nil { 220 return 221 } 222 var valueList []string 223 for _, column := range data.ColumnList { 224 str := dialect.GetStringValue(data.Data[column.ColumnName]) 225 str = strings.ReplaceAll(str, "\r\n", this_.GetLinefeed()) 226 str = strings.ReplaceAll(str, "\n", this_.GetLinefeed()) 227 str = strings.ReplaceAll(str, "\r", this_.GetLinefeed()) 228 valueList = append(valueList, str) 229 } 230 231 _, err = this_.saveFile.WriteString(strings.Join(valueList, this_.GetTextSeparator()) + "\n") 232 if err != nil { 233 return 234 } 235 236 return 237 } 238 239 func isRowEnd(rowInfo string) (isEnd bool) { 240 241 var inStringLevel int 242 var inStringPack byte 243 var thisChar byte 244 var lastChar byte 245 246 var stringPackChars = []byte{'"', '\''} 247 for i := 0; i < len(rowInfo); i++ { 248 thisChar = rowInfo[i] 249 if i > 0 { 250 lastChar = rowInfo[i-1] 251 } 252 253 // inStringLevel == 0 表示 不在 字符串 包装 中 254 if thisChar == ';' && inStringLevel == 0 { 255 } else { 256 packCharIndex := dialect.BytesIndex(stringPackChars, thisChar) 257 if packCharIndex >= 0 { 258 // inStringLevel == 0 表示 不在 字符串 包装 中 259 if inStringLevel == 0 { 260 inStringPack = stringPackChars[packCharIndex] 261 // 字符串包装层级 +1 262 inStringLevel++ 263 } else { 264 // 如果有转义符号 类似 “\'”,“\"” 265 if lastChar == '\\' { 266 } else if lastChar == inStringPack { 267 // 如果 前一个字符 与字符串包装字符一致 268 inStringLevel-- 269 } else { 270 // 字符串包装层级 -1 271 inStringLevel-- 272 } 273 } 274 } 275 } 276 277 } 278 isEnd = inStringLevel == 0 279 return 280 }