How to connect to SQL Server with Flutter? - sql-server

I have to use SQL Server with Flutter and I don't have another database option because my client has it. I was looking for packages but I only found a package that doesn't run on mobile. Is there any option to do that without web services or api?

The first thing that you need to consider is that there is no immediate and extremely effective solution and you have to decide what frameworks and tools to be used. And as mentioned in the comment that the market for this scenario is very small. But there are some ways that you can handle this.
Remote storage sample solution:
Here is a basic example of how you should implement this. It was also cited in this SO post:
Client application
The client application can be any application the user typically uses.
Some examples:
Mobile app (written in native, Dart, Xamarin, ...)
Desktop app (Electron, WPF, ...)
Website app (Angular, React, Vue, ...)
API
The API is there to retrieve data, and change data. But It will also
handle authentication, authorization, logging, doing business logic
Database
Your API will then execute queries, inserts, updates, deletes, execute
stored procedures on the Database of your choice. In your example SQL
Server.
There are many possibilities on how to set this up, depending on your
skills, knowledge of frameworks, how you want to deploy things.
How you want to deploy this will limit your choices as well. For your
API:
Serverless API (Via Azure Functions, AWS Lambda)
Cloud Website (Azure Web Apps)
Website hosted on premise
Docker container
In real life scenarios this often gets more complex with Firewalls,
Application Gateways, Virtual networks, clusters.

You can install a SQLServerSocket on your server:
https://github.com/nippur72/SqlServerSocket
Install and execute SqlServerSocket.exe in the background on the server machine where SQL Server is installed.
Also, you need a client:
https://github.com/nippur72/SqlServerSocket/tree/master/DartClient
And you can try some connections and queries directly to your DDBB:
// creates a connection
var conn = new
SqlConnection("SERVER=localhost;Database=mydb;Trusted_connection=yes");
// open connection
await conn.open();
// runs a query returning a single value
var howmany = await conn.queryValue("SELECT COUNT(*) FROM Customers");
// runs a query returning a single row
var myFirstCustomer = await conn.querySingle("SELECT name,age FROM Custormers");
print(myFirstCustomer["name"]);
// runs a query returning all rows
var customers = await conn.query("SELECT TOP 10 name,age FROM Custormers");
for(var customer in customers)
{
print(customer["name"]);
}
// execute a command, returning the number of rows affected
var n = await conn.execute("UPDATE Customers SET age=0");
print("zeroed $n customers");
// disconnect
await conn.close();

Related

Sequelize returning old data from SQL Server

Problem: what I'm sometimes seeing is that very old data is being returned from my various databases when I do SELECT operations (findAll).
I have a VueJS app in which I'm using AxiosJS to call my backend ExpressJS app which uses Sequelize to connect to several (4) SQL Server databases. I'm also using the VueJS Developer Tools so I can see the variables and Vuex store change in real time on the frontend. I'm also using console.log on the backend so I can see some things there too.
In searching for solutions, I have found that:
I'm not using transactions; all of my queries are single queries that return results to the application, so I don't (shouldn't) have issues with commit timing; i.e. I UPDATE or ADD a row and only after it returns a result do I then make a SELECT
Sequelize keeps connections open, and so old connections show as "Sleeping" in the DB; I see these do get reused over time
I'm using the default isolation level in SQL Server which is READ COMMITTED and which should return committed data; since I'm waiting for the first query to return a result before launching the second query, shouldn't it be committed and ready to get me the latest values?
I see that SQL Server CAN store old copies of rows, sometimes making SNAPSHOTS, but I think they require higher isolation levels - but I'm not sure about that; maybe it IS keeping old versions?
I've been unsuccessful in figuring out how to close and reopen Sequelize connections. I'd like to close things at logout and reconnect there too since the app is still running in the tab (if this will solve my old data problem), thereby allowing someone to relogin and open all of the DB connections to be available again. I can't figure it out based on the available docs.
I think Sequelize is using old connections and somehow it is that which is causing SELECT results to be stale - this is even more likely if SQL Server is keeping old versions of rows
For some reason, if I logout and do a hard refresh of my app (CTRL+F5), all data is fresh; I don't understand why this would be at all. What could the browser be holding on to? Note that the console logs on the server app are always consistent with whatever the frontend shows. In other words, if the backend console log is stale, the frontend is stale; if backend is fresh, frontend is too.
I am unable to duplicate the getting of stale data using SSMS or Postman
Question: So what are the possible ways I can be getting stale data when I'm using Axios on the frontend and Sequelize on the backend?

NodeJS - Get record from SQL Server and pass to a Webservice

What's best algorithm for this issue using by nodejs:
get N million records (streaming) from a SQL Server database
after getting a record, pass that to a web service
get result from web service and update that a record
I don't want to keep all records in server's memory
I would suggest here to take a look at the stream api from nodejs
https://nodejs.org/api/stream.html
Some possible (untested) example code here where pipe is used to get the data, make the request to the web service and perform an update.
let MssqlReadableStream = new MssqlClient({objectMode: true}).getRecords();
let HttpRequestServiceStream = new HttpRequestServiceStream({objectMode: true});
let MssqlWritableStream = new MssqlClient({objectMode: true}).updateRecord;
MssqlReadableStream
.pipe(HttpRequestServiceStream)
.pipe(MssqlWritableStream);

Connect to Mongodb from Angular, from where?

I have this admin panel template that's built in nodejs, jquery and angular.
I am trying to connect it to a mongodb to make simple CRUD operations.
I've installed mongojs via npm for this purpose but how do I take it from here? The Datebase itself is already set up and ready for use.
I tried to follow the instructions but I am not quite sure where to put the code that connects to the database.
var databaseUrl = "mydb"; // "username:password#example.com/mydb"
var collections = ["users", "reports"]
var db = require("mongojs").connect(databaseUrl, collections);
I've understood that it has to be on the server side as the client side won't run the require('mongojs') part. But in what file should it preferably be placed? And if it's put in the server side code how do I reach the 'db' object from the client side when making the CRUD operations?
Thanks in advance!
The server and the clients are different devices that interact by HTTP. Consider them as different projects that can luckily execute same chunks of code just because they are written in the same language. DB connection is not this kind of chunk.
Client doesn't connect to the database. You can't give db access to all your clients. Actually db should not be accessible from the Internet at all for security reasons.
Client makes HTTP requests to the server. Server fetches the db data and returns it back to the client. It is the main purpose of almost all servers.
This data updates the state of the models in your controller code.

Authentication with AngularJS - NodeJS

I cant figure out how to do a simple Authentication in my AngularJS app.
What would be the best and easiest way to do a normal server side authentication with my Setup:
Yeoman angular generator, running grunt server on :9000.
Does anyone have a good tutorial? or any tips?
Another question, what is the simplest way to store data with this setup? using MongoDB?
Thank you :)
AngularJS is a front-end JavaScript framework, you can use anything of your choice, loving and knowing at the back-end for your application. This question was something like you are asking "I am using HTML5, what should I use at my back-end?" Angluar can be used with many server-side languages, viz. Ruby, Node, PHP.
There is an awesome tutorial talking about Ruby on Rails + Angular by David Bryant Copeland.
If you want to use PHP, you could use any framework which comforts you, there are many
available. CodeIgniter is one of the popular PHP framework.
If you want to use Node for your application, Passport.js could
be something of interest. MEAN Stack is the new thing which is coming up, MEAN stands for MongoDB + Express.js + Angular.js + Node.js. There is a ready Yoeman generator for MEAN stack available.
Again depending upon the requirement you should choose between SQL or NoSQL database. Also depends upto certain extend on the choice of the server-side language.
If you need a scalable database which stores hierarchical data, NoSQL should be your choice. MongoDB is a popular NoSQL database; CouchDB, RethinkDB are other alternatives.
SQL database are used where application needs high transaction. Though we can use NoSQL database for transaction based application, but it is not stable in comparision to SQL databases. MySQL is the most commonly used SQL database.
Angularjs is really not involved in the authentication process.
The basic flow of authentication is quite simple:
You make a post request from your 'Angularjs app' (your client side application) to your server, passing as parameters a pair of username/password.
Then, on your nodejs application (server side) you query your database looking for the username provided and you try to match the password that was sent within the post request with the password you have stored in your database related to that user. If they matches, you set up a cookie on user's client which is related to a session stored in your database.
To make this simpler there are some libraries that help you.
You could use passport.js (http://passportjs.org/) together with express (http://expressjs.com/). Passport will help you setting up with ease the authentication process in a safe way and express will give you tools like the cookie parser, support for session and other tools you will need to use. Express will help you also setting an endpoint where you will post the request for logging in to.
Last thing, for storing data, you can use any database you want.
Nodejs has a relevant number of third party libraries that help interfacing with databases. If you want to use mongodb, this library (https://github.com/mongodb/node-mongodb-native) will make your life easy.
Your best bet would be to use the angular-fullstack generator as it comes with basic authentication -- both local and oAuth -- built in. From there, you can either just use the authentication that is setup for you or you can use it as a reference to help you figure out how its all working.
The easiest setup I am using is:
NodeJS / Express / Passport / Socket.io / MongoDB (can be anything else actually)
AngularJS
Express is handling all the security with Passport (there's a passport method being added to express req automatically that gives you an ability to check whether user is authenticated or not). It's called isAuthenticated and you can use it like below:
function loggedOnly(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect('/');
}
}
Route / & /login are public, but when user is logged in, they redirect to /app.
Route /app is Angular app which is private and redirects to /login when user is not authenticated.
app.get('/', anonOnly);
Socket.io has passport.socketio middleware for automatically refusing unauthorised connections that may occur.
Then, I access user object by doing the following:
io.on('connection', function(socket) {
var user = socket.conn.request.user;
});
To sum up, login logic is handled by static Express views. Moreover, Express prints few constant's to Angular app containing e.g. userData. Quite useful for displaying e.g. userName at some point.
Although it may take some time to set that up, it's definitely worth doing if you want to understand the whole logic of your app. I've given you the names of open-source packages to use, all the details can be found in their readme & guides (lots of them already exists if you google for a while).

Azure MobileServices Live/UAT/Dev environments

I have an azure mobile service that will go live at some point. So I need to create UAT and dev versions which would point to the UAT and dev databases. What I am struggling with is how to create these.
The namespace in my live, UAT and Dev databases need to be the same but if I create a new mobile service called myAppName_UAT, it's going to want to use MyAppName_UAT as the namespace and so will not find any of the tables.
Has anyone overcome this problem? Once the product goes live I'll need to be able to test the mobile apps against the Dev db without affecting live which surely must be a common scenario?
Any advice would be very gratefully received.
Edit: What I'm specifically after is how to manage the multiple environments within the Azure Portal. I can deploy all the other components of my UAT environment but I'm stuck on the mobile service.
I am not asking for a way for my applications to switch config files or to migrate data between databases. Does anyone have any experience of running azure applications with multiple components where they ran multiple mobile services?
Do you use a Version Control? For me, you just need to create branches to separate the 'UAT' and 'dev' versions.
About the databases:
You can use web.config transformations to switch the connection string between your databases.
http://msdn.microsoft.com/en-us/library/dd465326.aspx
How do I use Web.Config transform on my connection strings?
=================================================================================
Update:
Ok, now I understood what you want.
Create your two versions of mobile services:
1-Log in Windows Azure Management Portal (http://manage.windowsazure.com)
2-Create your test mobile services (if you already have then, skip this step):
2.1- New -> Compute -> Mobile Services
2.2- Url - MyMobileServicesTest
2.3- Database -> Create a new (test db).
3-Create your production mobile services (if you already have then, skip this step):
2.1- New -> Compute -> Mobile Services
2.2- Url - MyMobileServicesProduction
2.3- Database -> Create a new (production db).
Right now, you have two different versions.
Using Windows Azure SDK:
//public static MobileServiceClient MobileService = new MobileServiceClient(
// "AppUrl",
// "AppKey"
//);
Pay attention: AppUrl will be "MyMobileServicesTest.azure-mobile.net/" or "MyMobileServicesProduction.azure-mobile.net/". The app key, each environment will have it's own. You can store this settings in a config file and switch according to what you are doing.
More information:
http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-with-data-dotnet/
Multiple mobile services can share the same database. You only need to specify the same schema name in web.config in each mobile service:
<appSettings>
<add key="MS_MobileServiceName" value="MyAppName" />
</appSettings>
Updated:
The setting above only works in localhost, but not after publishing to live.
Need to do the following trick in order to make it work. Just hard code the schema name into function OnModelCreating. This way the database schema name will not depend on the mobile service name any more:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
string schema = "MyAppName"; // ServiceSettingsDictionary.GetSchemaName();
if (!string.IsNullOrEmpty(schema))
{
modelBuilder.HasDefaultSchema(schema);
}
modelBuilder.Conventions.Add(
new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
"ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
}

Resources