#sql-server #flutter #dart #dependencies #sqlconnection
Вопрос:
// Copyright (c) 2015, <your name>. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.
library sql_server_socket_test;
import '../lib/sqlconnection.dart';
import '../lib/table.dart';
import '../lib/sqlformats.dart';
import 'dart:async';
//Error occurs here(Couldn't get pub because of wrong version specification)
import "package:guinness/guinness.dart";
void main()
{
defineSpecs().then((_){});
}
Future defineSpecs() async
{
/// creates a common database where to perform all tests
var conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=master;Trusted_Connection=yes;");
//var conn = new SqlConnection("Server=DEVIL\SQLEXPRESS;Database=master;User Id=sa;Password=;");
await conn.open();
await conn.execute("IF EXISTS (SELECT name FROM master.sys.databases WHERE name = 'sql_server_socket_test_db') DROP DATABASE sql_server_socket_test_db");
await conn.execute("CREATE DATABASE sql_server_socket_test_db");
await conn.execute("USE sql_server_socket_test_db");
await conn.execute("CREATE TABLE Customers (Id INT IDENTITY PRIMARY KEY, Name VARCHAR(64), Age INT, Born DATETIME, HasWebSite BIT NOT NULL)");
await conn.execute("INSERT INTO Customers (Name, Age, HasWebSite) VALUES ('Bob' ,33, 0)");
await conn.execute("INSERT INTO Customers (Name, Age, HasWebSite, Born) VALUES ('Tom' ,42, 1, ${sqlDate(new DateTime(1972,05,03))})");
await conn.execute("INSERT INTO Customers (Name, Age, HasWebSite) VALUES ('Mary',18, 1)");
await conn.close();
conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=sql_server_socket_test_db;Trusted_Connection=yes;");
//conn = new SqlConnection("Server=DEVIL\SQLEXPRESS;Database=sql_server_socket_test_db;User Id=sa;Password=;");
describe("SQL formatting functions", ()
{
describe("sqlDate()", ()
{
it("returns a SQL formatted date", ()
{
var d = sqlDate(new DateTime(1980,5,3));
expect(d).toEqual("CONVERT(DATETIME,'1980-05-03 00:00:00.000',102)");
});
});
describe("sqlBool()", ()
{
it("converts true and false into 1 and 0", ()
{
expect(sqlBool(false)).toEqual("0");
expect(sqlBool(true )).toEqual("1");
});
});
describe("sqlString()", ()
{
it("sqlString() formats a string to SQL, keeping care of single quotes", ()
{
expect(sqlString("ONE'TWO''THREE'''")).toEqual("'ONE''TWO''''THREE'''''''");
});
});
});
// TODO connection tests (ports/service running etc)
describe('SqlConnection methods', ()
{
beforeEach(() async
{
await conn.open();
});
afterEach(() async
{
await conn.close();
});
describe("execute()", ()
{
it("returns the number of rows effected", () async
{
var n = await conn.execute("UPDATE Customers SET HasWebSite=1 WHERE HasWebSite=1");
expect(n).toEqual(2);
});
it("does UPDATE commands correctly when not changing anything", () async
{
var n = await conn.execute("UPDATE Customers SET HasWebSite=1 WHERE HasWebSite=1");
expect(n).toEqual(2);
});
it("returns 0 when nothing done", () async
{
var n = await conn.execute("UPDATE Customers SET HasWebSite=1 WHERE 0=1");
expect(n).toEqual(0);
});
it("does UPDATE commands correctly", () async
{
var n = await conn.execute("UPDATE Customers SET Name='Bill' WHERE Name='Bob'");
expect(n).toEqual(1);
var n1 = await conn.queryValue("SELECT COUNT(*) FROM Customers WHERE Name='Bob'");
var n2 = await conn.queryValue("SELECT COUNT(*) FROM Customers WHERE Name='Bill'");
expect(n1).toEqual(0);
expect(n2).toEqual(1);
n = await conn.execute("UPDATE Customers SET Name='Bob' WHERE Name='Bill'"); // reverts back
expect(n).toEqual(1);
});
});
describe("queryValue()", ()
{
it("returns null when querying empty rows", () async
{
// no customers named 'Mark'
var n = await conn.queryValue("SELECT Name FROM Customers WHERE Name='Mark'");
expect(n,null);
});
it("returns an integer value from query", () async
{
// Mary's Age is 18
var age = await conn.queryValue("SELECT Age FROM Customers WHERE Name='Mary'");
expect(age,18);
});
it("returns a boolean from query", () async
{
// Mary has a web site
var bit = await conn.queryValue("SELECT HasWebSite FROM Customers WHERE Name='Mary'");
expect(bit,true);
});
it("returns a String from query", () async
{
// Bob does not have a website
var name = await conn.queryValue("SELECT Name FROM Customers WHERE HasWebSite=0");
expect(name,"Bob");
});
it("returns null when queried field is null", () async
{
// First customer does not have a date
var born = await conn.queryValue("SELECT Born FROM Customers");
expect(born,null);
});
it("returns a DateTime from query", () async
{
var tomsborn = await conn.queryValue("SELECT Born FROM Customers WHERE Name = 'Tom'");
expect(tomsborn is DateTime).toEqual(true);
expect(tomsborn).toEqual(new DateTime(1972,05,03));
});
});
describe("querySingle()", ()
{
it("returns null when querying empty rows", () async
{
// no customers named 'Mark'
var n = await conn.querySingle("SELECT Name FROM Customers WHERE Name='Mark'");
expect(n).toEqual(null);
});
it("returns a row from query", () async
{
// tom's row
var row = await conn.querySingle("SELECT * FROM Customers WHERE Name='Tom'");
expect(row is Map).toEqual(true);
expect(row).toEqual({ "Id": 2, "Name": 'Tom' , "Age": 42, "HasWebSite": true, "Born": new DateTime(1972,05,03) });
});
});
describe("query()", ()
{
it("returns an empty List when querying empty rows", () async
{
// no customers named 'Mark'
var q = await conn.query("SELECT Name FROM Customers WHERE Name='Mark'");
expect(q).toEqual([]);
});
it("returns rows from query", () async
{
var q = await conn.query("SELECT Name, Age, HasWebSite, Born FROM Customers ORDER BY Id");
expect(q is List).toEqual(true);
expect(q.length).toEqual(3);
expect(q).toEqual(
[
{ "Name": 'Bob' , "Age": 33, "HasWebSite": false, "Born": null },
{ "Name": 'Tom' , "Age": 42, "HasWebSite": true, "Born": new DateTime(1972,05,03) },
{ "Name": 'Mary', "Age": 18, "HasWebSite": true, "Born": null }
]);
});
});
describe("queryTable()", ()
{
it("when result is empty, returns no rows and filled column info", () async
{
// no customers named 'Mark'
var table = await conn.queryTable("SELECT Name FROM Customers WHERE Name='Mark'");
expect(table.rows.length).toEqual(0);
expect(table.columns.length).toEqual(2); // Primary key Id is always included
});
it("returns a full datased", () async
{
// no customers named 'Mark'
var table = await conn.queryTable("SELECT Id, Name, Age, HasWebSite, Born FROM Customers ORDER BY Id");
expect(table.tableName).toEqual("Customers");
expect(table.rows.length).toEqual(3);
expect(table.columns.length).toEqual(5);
expect(table.rows).toEqual(
[
{ "Id": 1, "Name": 'Bob' , "Age": 33, "HasWebSite": false, "Born": null , "_originalIndex": 0 },
{ "Id": 2, "Name": 'Tom' , "Age": 42, "HasWebSite": true, "Born": new DateTime(1972,05,03) , "_originalIndex": 1 },
{ "Id": 3, "Name": 'Mary', "Age": 18, "HasWebSite": true, "Born": null , "_originalIndex": 2 }
]);
});
});
});
}
library sql_server_socket;
import "dart:io";
import "dart:async";
import "dart:convert";
import 'dart:typed_data';
import "table.dart";
class SqlConnection {
late Socket _socket;
late StringBuffer _receiveBuffer;
late Completer _completer;
late bool _connected;
late String _address;
late int _port;
late String _connectionString;
SqlConnection(String connStr,
{String address: "localhost", int port: 10980}) {
_address = address;
_port = port;
_connected = false;
_connectionString = connStr;
}
/// tells if database is connected
bool get connected => _connected;
/// connects to sql server database using the specified connection string
Future<bool> open() async {
try {
this._socket = await Socket.connect(_address, _port);
//print("Connected to: ${_socket.remoteAddress.address}:${_socket.remotePort}");
} catch (ex) {
// throw "can't connect to ${_address}:${_port} -- $ex";
throw "can't connect to $_address:$_port -- $ex";
}
//Establish the onData, and onDone callbacks
_socket
.transform(utf8.decoder as StreamTransformer<Uint8List, dynamic>)
.listen(_receiveData, onError: _onError, onDone: _onDone);
Completer<bool> connectCompleter = new Completer();
// String json = JSON.encode({"type": "open", "text": _connectionString});
String json = jsonEncode({"type": "open", "text": _connectionString});
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _OkResult) {
_connected = true;
connectCompleter.complete(true);
} else if (res is _ErrorResult) {
_connected = false;
connectCompleter.completeError(res.error);
} else
throw "unknown response";
}).catchError((err) {
_connected = false;
connectCompleter.completeError(err);
});
return connectCompleter.future;
}
/// disconnects from sql server
Future<bool> close() {
if (!connected) throw "not connected";
Completer<bool> disconnectCompleter = new Completer();
String json = jsonEncode({"type": "close", "text": ""});
_sendCommand(json).then((risp) {
var res = _parseResult(risp);
if (res is _OkResult) {
_connected = false;
disconnectCompleter.complete(true);
} else if (res is _ErrorResult) {
disconnectCompleter.completeError(res.error);
} else
throw "unknown response";
}).catchError((err) {
disconnectCompleter.completeError(err);
});
return Future.value(disconnectCompleter.future);
}
/// launch a query on the database, returning a table
Future<Table> queryTable(String sql) {
if (!connected) throw "not connected";
String json = jsonEncode({"type": "table", "text": sql});
Completer<Table> compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _TableResult) {
var tres = res;
Table tab = new Table(this, tres.tableName, tres.rows, tres.columns);
compl.complete(tab);
} else
throw "unknown response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
Future<PostBackResponse> postBack(ChangeSet chg) {
if (!connected) throw "not connected";
String params = jsonEncode(chg.toEncodable());
String json = jsonEncode({"type": "postback", "text": params});
Completer<PostBackResponse> compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _PostBackResult) {
var tres = res;
PostBackResponse resp = new PostBackResponse();
resp.idcolumn = tres.idcolumn;
resp.identities = tres.identities;
compl.complete(resp);
} else
throw "invalid postback response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
/// launch a query on the database, returning all rows
Future<List<Map<String, dynamic>>> query(String sql) {
if (!connected) throw "not connected";
String json = jsonEncode({"type": "query", "text": sql});
Completer<List<Map<String, dynamic>>> compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _QueryResult)
compl.complete(res.rows);
else
throw "unknown response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
/// launch a query on the database, returning the first rows only
Future<Map<String, dynamic>> querySingle(String sql) {
if (!connected) throw "not connected";
String json = jsonEncode({"type": "querysingle", "text": sql});
Completer<Map<String, dynamic>> compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _QueryResult) {
if (res.rows.length == 0)
compl.complete(null);
else
compl.complete(res.rows[0]);
} else
throw "unknown response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
/// launch a query on the database, returning the value from the first column of the first row
Future<dynamic> queryValue(String sql) {
if (!connected) throw "not connected";
String json = jsonEncode({"type": "queryvalue", "text": sql});
Completer compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _QueryResult) {
if (res.rows.length == 0)
compl.complete(null);
else
compl.complete(res.rows[0]["value"]);
} else
throw "unknown response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
/// executes a sql command, returning the number of rows affected
Future<int> execute(String sql) {
if (!connected) throw "not connected";
String json = jsonEncode({"type": "execute", "text": sql});
Completer<int> compl = new Completer();
_sendCommand(json).then((result) {
var res = _parseResult(result);
if (res is _ErrorResult)
compl.completeError(res.error);
else if (res is _QueryResult) {
if (res.rows.length == 0)
compl.complete(-1);
else
compl.complete(res.rows[0]["rowsAffected"]);
} else
throw "unknown response";
}).catchError((err) {
compl.completeError(err);
});
return compl.future;
}
/// formats and write a command to the socket
Future<String> _sendCommand(String command) {
// prepare buffer for response
_receiveBuffer = new StringBuffer();
Completer<String> _completer = new Completer();
String cmd = command.length.toString() "rn" command;
_socket.write(cmd);
return _completer.future;
}
void _onDone() {
//print("onDone()");
//socket.destroy();
}
void _onError(error) {
print("error occurred: $error");
}
/// receive data from socket and build a command string
///
/// client sends text-based commands with the format:
/// size_of_command_string "rn" command_string
void _receiveData(data) {
_receiveBuffer.write(data);
String content = _receiveBuffer.toString();
if (content.indexOf("rn") > 0) {
int x = content.indexOf("rn");
int len = int.parse(content.substring(0, x)); // size of command string
String cmd = content.substring(x 2);
if (cmd.length == len) {
_completer.complete(cmd);
}
}
}
/// translates generic json result into a Result type
dynamic _parseResult(String json) {
Map result = jsonDecode(json);
if (result["type"] == "ok")
return new _OkResult("ok");
else if (result["type"] == "error")
return new _ErrorResult(result["error"]);
else if (result["type"] == "query")
return new _QueryResult(result["rows"], result["columns"]);
else if (result["type"] == "table")
return new _TableResult(
result["tablename"], result["rows"], result["columns"]);
else if (result["type"] == "postback")
return new _PostBackResult(result["idcolumn"], result["identities"]);
else
throw "unknown response";
}
}
class _ErrorResult {
late String error;
_ErrorResult(String error) {
this.error = error;
}
}
class _OkResult {
late String ok;
_OkResult(String ok) {
this.ok = ok;
}
}
class _QueryResult {
late List<Map<String, dynamic>> rows;
late Map<String, dynamic> columns;
_QueryResult(List<Map<String, dynamic>> rows, Map<String, dynamic> columns) {
this.rows = rows;
this.columns = columns;
// fix types
for (var fieldName in columns.keys) {
TypeFixer.fixColumn(rows, fieldName, columns[fieldName]);
}
}
}
class _TableResult {
late String tableName;
late List<Map<String, dynamic>> rows;
late List<Map<String, String>> columns;
_TableResult(String tableName, List<Map<String, dynamic>> rows,
List<Map<String, String>> columns) {
this.tableName = tableName;
this.rows = rows;
this.columns = columns;
}
}
class _PostBackResult {
late String idcolumn;
late List<int> identities;
_PostBackResult(String idcolumn, List<int> identities) {
this.idcolumn = idcolumn;
this.identities = identities;
}
}
/// translates a JSON encoded SQL type into a Dart type
class TypeFixer {
/// fix string data type coming from JSON into proper Dart data type
static void fixColumn(
List<Map<String, dynamic>> rows, String columnName, String columnType) {
if (columnType == "datetime") {
for (int t = 0; t < rows.length; t ) {
if (rows[t][columnName] != null)
rows[t][columnName] = DateTime.parse(rows[t][columnName]);
}
}
}
}
pubspec.yaml
name: sql_server_socket
version: 0.0.1
description: A minimal command-line application.
#author: <Antonino Porcino> <nino.porcino@gmail.com>
#homepage: https://github.com/nippur72/SqlServerSocket
environment:
sdk: ">=2.7.0 <3.0.0"
#dependencies:
# foo_bar: '>=1.0.0 <2.0.0'
dev_dependencies:
unittest: any
guinness: ">=1.3.0 <2.0.0"
I’m using Flutter Dart to develop an application, in that I’m trying to establish Sql connection with Sql server and application.
This is the link I referred for connection https://github.com/nippur72/SqlServerSocket .
While trying to add dependencies in pubspec.yaml, under dev_dependencies the version of guinness is not updating to the newer version(pub update). While clicking pub get i’m receiving this error,
Устранение зависимостей… Поскольку sql_server_socket зависит от guinness ^1.3.0, который не соответствует ни одной версии, решение версии не удалось. Процесс завершен с кодом выхода 1
Я попытался указать версию вручную, и я знаю, что это не работает таким образом. Поэтому я использовал обновление паба, попытался обновить всю версию flutter и dart, но получил ту же ошибку. Есть ли какое-либо другое решение, кроме гиннесса? Или как я могу получить настоящую версию книги Гиннесса. Я пробовал серфить по Интернету в поисках версий Гиннесса, но не получил соответствующего результата. Пожалуйста, помогите мне с этим вопросом. Последние несколько дней я застрял с подключением к sql.
Заранее спасибо!
Сообщение об ошибке
Комментарии:
1. Вы уверены, что ваше приложение должно напрямую подключаться к серверу базы данных? В большинстве случаев это кажется очень небезопасным.
2. @nvoigt Я разрабатываю это приложение для автономного использования, и оно должно храниться локально. В этом случае вместо использования интеграции API я выбрал этот метод. Есть ли какое-либо решение вместо прямого подключения к серверу базы данных? Если да, то не могли бы вы помочь мне с этим, пожалуйста
3. Если его нужно хранить локально, SQL Server-очень странный выбор для приложения Flutter. Вы программируете приложение Flutter только для Windows, или я что-то пропустил в SQL Server?
4. Как вы сказали «в автономном режиме» и «локально», я предполагаю, что вы программируете не веб-приложение, а действительно приложение на устройствах. Вы заглядывали в pub.dev/пакеты/sqflite ?
5. Я разрабатываю мобильное приложение и пытаюсь использовать существующую базу данных MSSQL в Flutter. Итак, проблема в том, что я не смог загрузить внешнюю базу данных в этот проект. Пакет Sqflite не поддерживает эту конкретную вещь. Я устал от SQLite studio, Microsoft SQL server management studio и т. Д. И, Наконец, решил перейти на MSSQL, потому что ранее используемая база данных не использует SQLite. Также первой ссылкой, которую я просмотрел, был pub.dev/packages/sqflite .В этом приложении версия не обновляется, даже если мы заставляем ее это делать. Что я могу сделать, чтобы устранить эту проблему? Любые предложения будут полезны