Пытаюсь подключить свое приложение к SQL Server с помощью sql_server_socket. В SqlConnection.dart версия пакета guinness не указана правильно

#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 .В этом приложении версия не обновляется, даже если мы заставляем ее это делать. Что я могу сделать, чтобы устранить эту проблему? Любые предложения будут полезны