У меня есть текстовый файл размером около 17 МБ, который мне нужно проанализировать, разбить его построчно и затем добавить в базу данных с помощью транзакций.
Если файл слишком большой и я пытаюсь открыть его, приложению не хватит памяти, поэтому я попытался прочитать его по частям, а затем импортировать каждый фрагмент в базу данных. Из-за транзакций введенные в БД данные неверны.
Есть часть используемого кода:
await file_reader.resolveLocalFilesystemUrl(path + file).then(async (file_entry: any) => {
await file_entry.file(async (file) => {
let reader = new FileReader();
reader.onprogress = async (reader_result: any) => {
let loaded = _.cloneDeep(reader_result.loaded);
let total = _.cloneDeep(reader_result.total);
let is_last_element: boolean = _.cloneDeep(loaded == total);
let i: number = 0;
let document_length = this.sync_parser.getReaderLength();
let event_type: number = this.sync_parser.getEventType();
content = iconv.encode(reader.result, encoding).toString();
await this.db.db.transaction(async (database: any) => {
while (document_length >= i) {
if (event_type == SyncParserIo.START_TAG) {
this.table = await this.newHeader(this.sync_parser.getName());
} else if (event_type == SyncParserIo.END_TAG) {
// this.file_content = null;
} else if (event_type == SyncParserIo.ROW) {
// here I execute basic_update_insert function
}
event_type = this.sync_parser.next(i);
i++;
}
}).then(()=>{
this.logger.info(this.TAG, "End document from transaction");
}).catch((e)=>{
//log
});
if (is_last_element) {
resolve(true);
}
};
await reader.readAsBinaryString(file);
});
}).catch((e) => {
this.logger.error("FileSystem Error", e.message);
return reject(e);
});
protected basic_update_insert(table, rows_map, where, where_bindings, database?) {
let db_query = database != null ? database : this.database;
let update_query_util: any = DbUtil.update(table, rows_map, where, where_bindings);
let insert_query_util: any = DbUtil.insert(table, rows_map);
this.import_result = null;
db_query.executeSql(update_query_util.query, update_query_util.bindings, (tx, res) => {
if (res.rowsAffected === 0) {
tx.executeSql(insert_query_util.query, insert_query_util.bindings, (tx2, insert_result) => {
if (insert_result.insertId != null) {
this.import_result = ImporterIo.RESULT_OK;
}
}, (e) => {
this.import_result = ImporterIo.ERROR_INSERT_ROW;
});
} else if (res.rowsAffected === 1) {
this.import_result = ImporterIo.RESULT_OK;
} else if (res.rowsAffected > 1) {
this.import_result = ImporterIo.RESULT_OK;
}
}, (e) => {
this.logger.error(this.TAG, `error from ${table} update`, e);
this.import_result = ImporterIo.ERROR_UPDATE_ROW;
});
}