I had an MYSQL Dumped database which I converted to SQLite and moved that into the assets folder in Flutter.
I am trying to open the database but it is throwing the following error:
E/SQLiteLog(29199): (8) statement aborts at 1: [PRAGMA user_version = 1] attempt to write a readonly database I/flutter (29199): error DatabaseException(attempt to write a readonly database (code 8 SQLITE_READONLY)) sql 'PRAGMA user_version = 1' args []} during open, closing...
Here is the code:
_initDatabase() async {
var databasePath = await getDatabasesPath();
var path = join(databasePath, "example.db");
var exists = await databaseExists(path);
if (!exists) {
print('creating a new copy from asset!');
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
ByteData data = await rootBundle.load(join("assets", "example.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(path).writeAsBytes(bytes, flush: true);
} else {
print('opening existing database');
}
return await openDatabase(path, version: _dbVersion, readOnly: true);
}
It doesn't throw an error in the above method but when I try to query (a simple SELECT for example).
I have searched similar questions but of no avail. Some are saying it is a permission issue and some are saying something different.
Can anyone please tell me what I am doing wrong?
Specifying a version during openDatabase is to perform database schema migration, hence not for read only mode. Just remove the version parameter and you should be fine:
await openDatabase(path, readOnly: true);
Related
I'm executing several insert and update statemens in a squence using the same prisma client variable, all wrapped in a try catch.
In the catch, I want to log the error to the database but I'm getting the error:
Invalid prisma.$executeRaw() invocation: Raw query failed. Code:
N/A. Message: N/A
This is what my code looks like:
let prisma = await new PrismaClient({
datasources: {
db: {
url: dbUrl,
},
},
});
try {
await prisma.$executeRaw`
INSERT INTO table1(col1, col2)
VALUES (val1, cal2);`;
await prisma.$executeRaw`
INSERT INTO table2(col1, col2)
VALUES (val1, cal2);`;
} catch (err: any) {
console.log('Error doing and sql insert: ' + err);
// Update the log item in the db with the error.
try {
console.log('getting ready to log sql error')
// We can't use the prisma variable above becuase it probably died when we got the error
// so create a new prisma variable here.
// The exception is on the next line.
let prisma2 = await new PrismaClient({
datasources: {
db: {
url: dbUrl,
},
},
});
await prisma2.$executeRaw`
UPDATE FisImportLog
SET Success = 0, Message = 'Error at: ${msg}. ' + ${err}
WHERE FisImportLogGUID = ${logId};`;
} catch (err: any) {
console.log('FIS Import *Log* Error Message: ' + err);
// This was really bad!!!
// Call notification service here
}
}
Can anyone tell me why I get this error and how I can log a prisma error to the db using prisma?
Thanks.
I found the problem thanks to the comment from #Shea Hunter Belsky
I was logging error messages from a Typescript try/catch and the err had lots of single quotes in it which totally corrupted the dynamic sql used for inserting the error message. I replaced them with ticks and then all worked.
But to do this I had to use the prisma.$executeRawUnsafe instead of prisma2.$executeRaw with a string template like this:
let errMessage = err.toString().replace(/'/g, "`")
let errorLogSQL = `
UPDATE FisImportLog
SET Success = 0, Message = 'Error at: ${msg}: ${errMessage}'
WHERE FisImportLogGUID = '${logId}';`;
await prisma.$executeRawUnsafe(errorLogSQL);
Note: I also had to wrap the ID in the where clause with single quotes where as in a string template I don't.
I have created a url scraper function, working and tested on Google Cloud, but I am really drawing a blank on how to invoke it. I have tried two methods, one using the cloud_functions package, and the other using a standard HTTPS get. I've tried looking online, but none of the solutions/guides involve functions with an input from the Flutter app, and an output back to the app.
Here's the structure of the function (which is working alright). I've named this function Parse in Google Cloud Platform.
<PYTHON PACKAGE IMPORTS>
def Parser(url):
<URL PARSE FUNCTIONS>
return source, datetime, imageurl, keyword
def invoke_parse(request):
request_json = request.get_json(silent=True)
file = Parser(request_json['url'])
return jsonify({
"source": file[0],
"datetime": file[1],
"imageurl": file[2],
"keyword": file[3],
})
The first method I tried was using an HTTP CALL to get the function. But that isn't working, even though there are no errors - I suspect it's just returning nothing.
parser(String url) async{ // Here I honestly don't know where to use the url input within the function
var uri = Uri.parse(<Function URL String>);
HttpClient client;
try {
var request = await client.getUrl(uri);
var response = await request.close();
if (response.statusCode == HttpStatus.ok) {
var json = await response.transform(utf8.decoder).join();
Map data = jsonDecode(json) as Map;
source = data['source']; // These are the variables used in the main Flutter app
postedAt = data['datetime'];
_imageUrl = data['image'];
keyword = data['keyword'];
} else {
print('Error running parse:\nHttp status ${response.statusCode}');
}
} catch (exception) {
print('Failed invoking the parse function.');
}
}
That didn't work, so I thought I might alternatively use the cloud_functions package as follows (in lieu of the previous):
parser(String url) async {
var functionUrl = <FUNCTION URL>;
HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(functionName: 'Parse')
..timeout = const Duration(seconds: 30);
try {
final HttpsCallableResult result = await callable.call(
<String, dynamic>{
'url': url,
}
);
setState(() {
source = result.data['source']; //THESE ARE VARIABLES USED IN THE FLUTTER APP
postedAt = result.data['datetime'];
_imageUrl = result.data['image'];
keyword = result.data['keyword'];
});
}
on CloudFunctionsException catch (e) {
print('caught firebase functions exception');
print(e.code);
print(e.message);
print(e.details);
} catch (e) {
print('caught generic exception');
print(e);
}
}
In the latter case, the code ran without errors but doesn't work. My flutter log states the following error:
I/flutter ( 2821): caught generic exception
I/flutter ( 2821): PlatformException(functionsError, Cloud function failed with exception., {code: NOT_FOUND, details: null, message: NOT_FOUND})
which I'm assuming is also an error at not being able to read the function.
Any help on how I should go about processing my function would be appreciated. Apologies if something is a really obvious solution, but I am not familiar as much with HTTP requests and cloud platforms.
Thanks and cheers.
Node Js Backend Function
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.test = functions.https.onCall(async (data, context) => {
functions.logger.info("Hello logs: ", {structuredData: true});
functions.logger.info( data.token, {structuredData: true});
}
Flutter frontend
1- pubspec.yaml
cloud_functions: ^1.1.2
2 - Code
HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('test');
final HttpsCallableResult results = await callable.call<Map>( {
'token': token,
});
I made saving the entity in the database.
public async saveTask(toDoDto: CreateToDoDto) {
try {
const toDo: ToDo = this.todosRepository.create(toDoDto);
return await this.todosRepository
.createQueryBuilder()
.insert()
.into(ToDo)
.values(toDo)
.execute();
} catch (err) {
this.logger.error(err.message);
throw new WsException(err.message);
}
}
When I save an entity to a database, I want it to be returned to me.
How can I get the just saved entity in the database?
return await this.todosRepository
.createQueryBuilder()
.insert()
.into(ToDo)
.values(toDo)
.returning('*')
.execute();
I cannot use the return function, as I get an error.
OUTPUT or RETURNING clause only supported by Microsoft SQL Server or PostgreSQL databases.
When I insert into the database without the return function, I get the following response.
InsertResult {
identifiers: Array(1),
generatedMaps: Array(1),
raw: OkPacket
}
And in this in the answer there is no entity that I wrote to the database.
How to get the recorded entity into the database if the return function is not working fuck mysql?
(MySQLi Object-oriented)
$last_id = $conn->insert_id; // $conn is the connection made to sql
(MySQLi Procedural)
$last_id = mysqli_insert_id($conn);
(PDO)
$last_id = $conn->lastInsertId();
I'm using this function from the Azure Blob Service library: https://azure.github.io/azure-storage-node/global.html#createBlobService
But its not allowing me to, When specifying the environmental variables in environment.ts it throws up this error: ERROR Error: Credentials must be provided when creating a service client.
And when trying to pass in the ConnectionString it throws this error: ERROR TypeError: crypto.createHmac is not a function
var azure = require('azure-storage');
var bs = azure.createBlobService();
bs.createContainerIfNotExists('taskcontainer', {
publicAccessLevel: 'blob'
}, function(error, result, response) {
if (!error) {
console.log("True");
// if result = true, container was created.
// if result = false, container already existed.
}
});
Has anyone had this problem before? would be great to see a solution
you should provide account name and storage key something like this:
var blobService = azure.createBlobService(environment.storage_account_name, environment.storage_key);
I'm trying to post some data from a dart project to another and store them in a mongoDB
Post code:
import 'dart:io';
void main() {
List example = [
{"source": "today", "target": "tomorrow"},
{"source": "yesterday", "target": "tomorrow"},
{"source": "today", "target": "yesterday"}
];
new HttpClient().post('localhost', 4040, '')
.then((HttpClientRequest request) {
request.headers.contentType = ContentType.JSON;
request.write(example);
return request.close();
});
}
Code that receives it, inside another file
void start() {
HttpServer.bind(address, port)
.then((HttpServer server) {
// Log in console to show that server is listening
print('Server listening on ${address}:${server.port}');
server.listen((HttpRequest request) {
request.transform(UTF8.decoder).listen(sendToDatastore);
});
});
}
void sendToDatastore(String contents) {
var dbproxy = new dbProxy("myDb");
dbproxy.write("rawdata", contents);
index++;
// non related to the problem code
}
bool write(collectionName, document)
{
Db connection = connect();
DbCollection collection = connection.collection(collectionName);
connection.open().then((_){
print('writing $document to db');
collection.insert(document);
}).then((_) {
print('closing db');
connection.close();
});
return true;
}
What I'm struggling with is that I'm using
request.transform(UTF8.decoder).listen(sendToDatastore);
so I'm converting the request stream to a string as I couldn't find the way to send it as Json.
And then in sendToDatastore I'm not able to parse it properly in order to store it. As far as I understand I'd need to get every Json object as a Map to store it as I'm getting this error
Uncaught Error: type 'String' is not a subtype of type 'Map' of 'document'.
Thanks,
UPDATE
If I try to do something like this in sendToDatastore
void sendToDatastore(String contents) {
var dbproxy = new dbProxy("myDb");
var contentToPass = JSON.decode(contents);
contentToPass.forEach((element) => dbproxy.write("rawdata", element));
index++;
// non related to the problem code
}
It raises this error
Uncaught Error: FormatException: Unexpected character (at character 3)
[{source: today, target: tomorrow}, {source: yesterday, target: tomorrow}, ...
^
In the use of JSON.decode
UPDATE2
The error was that I wasn't sending actual Json from the "post code". I used
// ...
request.write(JSON.encode(example));
// ...
and everything worked fine
Thanks
You should be able to use the dart:convert package.
You can then use:
String str = JSON.encode(obj)
and
var obj = JSON.decode(str)
to convert string/json.