Git Product home page Git Product logo

mysql's Introduction

SQLJocky

This is a MySQL connector for the Dart programming language. It isn't finished, but should work for most normal use. The API is getting reasonably close to where I want it to be now, so hopefully there shouldn't be too many breaking changes in the future.

It will only work in the command-line VM, not in a browser.

News

The changelog has now been moved to CHANGELOG.md

Usage

Create a connection pool:

var pool = new ConnectionPool(
    host: 'localhost', port: 3306,
    user: 'bob', password: 'wibble',
    db: 'stuff', max: 5);

Execute a query:

var results = await pool.query('select name, email from users');

Use the results: (Note: forEach is asynchronous.)

results.forEach((row) {
  print('Name: ${row[0]}, email: ${row[1]}');
});

Or access the fields by name:

results.forEach((row) {
  print('Name: ${row.name}, email: ${row.email}');
});

Prepare a query:

var query = await pool.prepare(
  'insert into users (name, email, age) values (?, ?, ?)');

Execute the query:

var result = await query.execute(['Bob', '[email protected]', 25]);

An insert query's results will be empty, but will have an id if there was an auto-increment column in the table:

print("New user's id: ${result.insertId}");

Execute a query with multiple sets of parameters:

var results = await query.executeMulti([['Bob', '[email protected]', 25],
    ['Bill', '[email protected]', 26],
    ['Joe', '[email protected]', 37]]);

Use the list of results:

for (result in results) {
  print("New user's id: ${result.insertId}");
}

Use a transaction:

var trans = await pool.startTransaction();
var result = await trans.query('...');
await trans.commit();

Development

To run the examples and tests, you'll need to create a 'connection.options' file by copying 'connection.options.example' and modifying the settings.

Licence

It is released under the GPL, because it uses a modified part of mysql's include/mysql_com.h in constants.dart, which is licensed under the GPL. I would prefer to release it under the BSD Licence, but there you go.

The Name

It is named after Jocky Wilson, the late, great darts player. (Hence the lack of an 'e' in Jocky.)

Things to do

  • Compression
  • COM_SEND_LONG_DATA
  • CLIENT_MULTI_STATEMENTS and CLIENT_MULTI_RESULTS for stored procedures
  • More connection pool management (close after timeout, change pool size...)
  • Better handling of various data types, especially BLOBs, which behave differently when using straight queries and prepared queries.
  • Implement the rest of mysql's commands
  • Handle character sets properly? Currently defaults to UTF8 for the connection character set. Is it necessary to support anything else?
  • Improve performance where possible
  • Geometry type
  • Decimal type should probably use a bigdecimal type of some sort
  • MySQL 4 types (old decimal, anything else?)
  • Test against multiple mysql versions

mysql's People

Contributors

astashov avatar faisalabid avatar ibala2012 avatar jamesots avatar kevmoo avatar mnordine avatar mnordine-gn avatar sethladd avatar tomcaserta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mysql's Issues

Status of stored procedure support?

I've been trying to call a stored procedure with sqljocky, however, this doesn't work.

I've used straight queries, prepared queries, queries in a connection, and they all fail with Error 1312 (0A000): PROCEDURE db.procedureName can't return a result set in the given context

_pool.query('CALL procedureName(1)')
        .then((testResults) => testResults.toList())
        .then((testResults) {

This procedure does return a result set.

Select For Update

There appears to be a problem with record locking. In my test program, I am Selecting a row “FOR UPDATE”, and being prevented in the same session from updating that same row. The program runs without a problem if I do a Select without locking the row, but obviously I need to lock the row.

Details are below. Let me know if you want the test program.

Apart from that, everything thus far runs well, and the package appears to be very fast.

Portion of code where error occurs :

async.Future<String> fUpdateData() {
  async.Completer<String> oCompleter = new async.Completer();
  String sResult;
  try {
    ogDb.query("Start Transaction").then((oResult){
      int iPos = ogRand1.nextInt(lgKeys.length);
      int iKey = lgKeys[iPos];
      String sSql1 = "SELECT ikey, dbalance FROM test01 WHERE iKey = ${iKey} FOR UPDATE";
      String sSql2 = "SELECT ikey, dbalance FROM test01 WHERE iKey = ${iKey} LOCK IN SHARE MODE";
      String sSql3 = "SELECT ikey, dbalance FROM test01 WHERE iKey = ${iKey}";
      ogDb.query(sSql1)
      .then((oResult){
        oResult.stream.listen((row) { 
          if (row == null) {
            sResult = "Select for Update failed to return one row. Rows = ${oResult}";
            ogDb.query("Rollback").then((oResult) => fPrint ("Rollback completed"));
            oCompleter.complete(sResult);
            return oCompleter.future;
          } else {  
            String sKey = "${row[0]}";       
            double dBalOld = row[1];
            String sAmt = fGetAmount(999);   // Get $cc amount
            double dBalNew = dBalOld + double.parse(sAmt);
            String sBalance1 = dBalOld.toStringAsFixed(2);
            String sBalance2 = dBalNew.toStringAsFixed(2);
            String sSql = "UPDATE test01 SET dBalance = $sBalance2 WHERE ikey = $sKey";
            ogDb.query(sSql).then((sRowsAffected) {
              ogDb.query("COMMIT")
              .then((oResult) {
                oCompleter.complete("Update Completed");
                return oCompleter.future;
              });
            })
           .catchError((oError) {
              print ("\nError attempting update. \nError = ${oError}");
              exit(1);
            });
          }       
        });
      });
    });

The details relating to the error are as follows (test program output) :

Testing SqlJocky Mysql
Cmd Line Args = []
Syntax = cmd -i number -p (y or n)
Defaults = '-i 1000' and '-p n'
opening MySql connection
Mysql connection opened
Clearing table
Table cleared
Returned from clearing table
01 1000 Iterations processed for Insert
02 Total elapsed seconds = 2.174
03 Average Insert elapsed millisconds = 2.17
Forming list of random keys for updates
Updating data

Error attempting update.
Error = Error 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

PB: query.executeMulti Mysql 5.5.24 SQLJOCKY 0.8.1

When i run the sample:an error occurs:
prepared query 1
Uncaught Error: MySQL Client Error: Connection #0 cannot process a request for Instance of '_ExecuteQueryHandler@0xf04aefa' while a request is already in progress for Instance of '_ExecuteQueryHandler@0xf04aefa'
Stack Trace:
#0 _Connection.processHandler (package:sqljocky/src/connection.dart:178:7)
#1 Query._execute (package:sqljocky/src/query.dart:112:37)
#2 Query.executeMulti..executeQuery (package:sqljocky/src/query.dart:139:19)
#3 Query.executeMulti..executeQuery. (package:sqljocky/src/query.dart:144:29)
#4 _Future._propagateToListeners. (dart:async/future_impl.dart:453)
#5 _rootRun (dart:async/zone.dart:683)
#6 _RootZone.run (dart:async/zone.dart:823)
#7 _Future._propagateToListeners (dart:async/future_impl.dart:445)
#8 _Future._complete (dart:async/future_impl.dart:303)
#9 _Future._asyncComplete. (dart:async/future_impl.dart:354)
#10 _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#11 _createTimer. (dart:async-patch/timer_patch.dart:11)
#12 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:151)
#13 _Timer._createTimerHandler. (timer_impl.dart:166)
#14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:93)

My version of dart is:
Dart Editor version 1.0.0_r30188 (STABLE)
Dart SDK version 1.0.0.3_r30188

Socket code optimistic

Email from Mads Ager:

I quickly browsed the code and it is looking good. On a quick reading,
the one thing I noticed was that the writing to sockets is a bit
optimistic:

https://github.com/jamesots/sqljocky/blob/master/lib/buffer.dart#L57
https://github.com/jamesots/sqljocky/blob/master/lib/transport/transport_impl.dart#L68

This will most likely break at some point when you cannot write all
the data in one write operation. Maybe add 'assert(written ==
expected)' after each use so you catch it when it breaks? There are a
couple of ways of dealing with this: either use the socket output
stream which will deal with this for you or buffer up data yourself
and hook up an onWrite handler that writes more data when the socket
is ready to deal with more again. The output stream is probably the
simplest.

query Never complete

In your example, if you change the main with

example.run().then(() {
example.run().then((
) {
print("K THNX BYE!");
});
pool.close();
});
the 2nd dropping table never completes.
In my software, it's an "insert query" that make this.
Best regards.

MYSQL 5.5.24
SQLJOCKY 0.8.3
Dart Editor version 1.0.0_r30188 (STABLE)
Dart SDK version 1.0.0.3_r30188

Can't execute prepared query with List as args.

Followed this example:

Prepare a query:

pool.prepare('insert into users (name, email, age) values (?, ?, ?)').then((query) {...});

Execute the query:

query.execute(['Bob', '[email protected]', 25]).then((result) {...});

My code:

pool.prepare('insert into session (name, userId, expires) values (?, ?, ?)').then((query) {
    query.execute(['md5(concat(CURRENT_TIMESTAMP, $id))', '$id', 'CURRENT_TIMESTAMP + $expirationTime']).then((result)  { /* ... */ });

DartEditor shows warning on this line:
0 positional arguments expected, but 1 found

Run fails with following error:
Uncaught Error: Class 'Query' has no instance method 'execute' with matching arguments.

Is it a bug? Maybe I'm doing something wrong?

is this secure for databases?

When a dart app is compiled to javascript, how does one prevent users from injecting their own javascript and modifying databases in ways you would not want them to? How do we prevent users from reading the connection information?

(Sorry if this is a bad place to pose this question)

"Uncaught Error: Bad state: Future already completed" when "SELECT"ing a .png

When saving a .PNG file that is 4630 bytes there is no issue. The data is in a LONGBLOB.

mysql --version:
mysql Ver 15.1 Distrib 5.5.37-MariaDB, for Linux (x86_64) using readline 5.1

the actual query used is:
SELECT * FROM content WHERE pathRaw=?;
["social/logo.png"]

The Stack Trace:
Uncaught Error: Bad state: Future already completed
Stack Trace:
#0 _AsyncCompleter.completeError (dart:async/future_impl.dart:35)
#1 _handleData (package:sqljocky/src/connection.dart:211:31)
#2 _rootRunUnary (dart:async/zone.dart:730)
#3 _RootZone.runUnary (dart:async/zone.dart:864)
#4 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#5 _Future._propagateToListeners (dart:async/future_impl.dart:571)
#6 _Future._completeWithValue (dart:async/future_impl.dart:331)
#7 _Future._asyncComplete. (dart:async/future_impl.dart:393)
#8 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#9 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)

in ShutdownIsolate: Unhandled exception:
Bad state: Future already completed
#0 _rootHandleUncaughtError.. (dart:async/zone.dart:713)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#3 _asyncRunCallback (dart:async/schedule_microtask.dart:36)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)

Minor Bug with Options

I just started using your library. Thanks for writing it. I'm writing a personal cash program ala Mint. It'll start very small and gradually grow. I did run into a couple of minor problems.

If you use a default value for port, the code faults. One fix is to check for null, before using parseInt.:

int getInt(String key, [int defaultValue]) {
var value = _map[key];
if (value != null) {
return Math.parseInt(value);
}
return defaultValue;
}

I run into another bug, if you run runTests twice. The code faults (see below). I haven't trace it down yet.

Unhandled exception:
NoSuchMethodException : method not found: 'get:hours'
Receiver: 2012-08-03 11:51:19.012
Arguments: []

Bound parameters with a value of (Dart) null don't get inserted as mysql NULLs.

I'm seeing Dart nulls getting inserted as the string "null" in mysql.

Is the expected behavior that sqljocky would translate Dart nulls into mysql NULLs, or do you have to do something special to get NULL in mysql?

For example:

String sql = 'UPDATE users SET name = ?';
List params = [null];

would yield a query of "UPDATE users SET name = 'null'", which is not the behavior I want.

SocketException when executing a query a long time after the previous query execution

Executing a query 8 hours or more after the previous query execution raises a SocketException.

This is the output from the test program below. It shows the first query working, but the query eight hours later fails.

2014-11-13 11:19:51.518: INFO: Duration: 8:00:00.000000
2014-11-13 11:19:51.524: INFO: do_a_query
2014-11-13 11:19:51.622: INFO: Got prepared query
2014-11-13 11:19:51.732: INFO: success (1 rows)
2014-11-13 19:19:51.733: INFO: do_a_query
2014-11-13 19:19:51.734: INFO: Got prepared query
2014-11-13 19:19:51.750: SEVERE: test: execute: SocketException: Write failed, address = localhost, port = 44804

Note: the problem does not occur if the delay is 7 hours or less.

When the SocketException occurs, the very next query executed also raises a SocketException. But queries immediately after that work... unless you wait another 8 hours and then it fails again. This behaviour is not demonstrated by the simple test program below.

This test program demonstrates the problem. Run it for 8 hours or longer.

import 'dart:io';
import 'dart:async';

import 'package:sqljocky/sqljocky.dart';
import 'package:logging/logging.dart';

final Duration duration = new Duration(hours: 8, minutes: 0, seconds: 0);
// 6 hours - ok
// 7 hours - ok
// 7 hours, 30 minutes - ok
// 8 hours triggers it
// 9 hours triggers it

String db_host = "localhost";
int db_port = 3306;
String db_user = "testuser";
String db_password = "password";
String db_name = "testdb";

final Logger log = new Logger('SQLjocky-SocketError-test');

ConnectionPool pool;

void do_a_query()
{
  log.info("do_a_query");

  pool.prepare("SELECT givenName, familyName FROM person").then((Query query) {

    query.execute([]).then((Results results) {

      var num_rows = 0;

      results.forEach((Row row) {
        var givenName = row[0];
        num_rows++;

      }).then((_) {
        log.info("success (${num_rows} rows)");
        var f = new Future.delayed(duration).then((_) { do_a_query(); });

      })
     .catchError((e) { log.severe("test: forEach: $e"); });
    })
    .catchError((e) { log.severe("test: execute: $e"); });
  })
  .catchError((e) { log.severe("test: prepare: $e"); });
}

//----------------------------------------------------------------

void main(List<String> arguments) {
  Logger.root.level = Level.INFO; // Change to Level.ALL to see everything
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.time}: ${rec.level.name}: ${rec.message}');
  });

  log.info("Duration: ${duration}");

  pool = new ConnectionPool(host: db_host, port: db_port,
                            user: db_user, password: db_password, db: db_name, max: 5);
  if (pool == null) {
    print("Error: could not create connection pool to database");
    exit(1);
  }

  do_a_query();
}

It expects a mySQL database that can be created like this:

CREATE DATABASE testdb;

USE testdb;

CREATE TABLE person (
  givenName varchar(255),
  familyName varchar(255)
);
INSERT INTO TABLE person
VALUES ("John", "Citizen");

CREATE USER testuser@'%' IDENTIFIED BY 'password';
GRANT ALL ON testdb.* to testuser@'%';

If the logging level is set to Level.ALL the following is outputted immediately before the SocketException occurs:

...
2014-11-11 16:27:28.277: FINE: Got an EOF
2014-11-11 16:27:28.278: FINEST: Response finished for #1, setting handler to null and waiting to release and reuse
2014-11-11 16:27:28.280: INFO: success (1 rows)
2014-11-11 16:27:28.280: FINEST: Releasing and reusing connection #1
2014-11-12 00:27:28.281: INFO: do_a_query
2014-11-12 00:27:28.282: FINE: Getting prepared query for: SELECT givenName, familyName FROM person
2014-11-12 00:27:28.282: FINEST: Getting a connection
2014-11-12 00:27:28.282: FINEST: Number of in-use connections: 0
2014-11-12 00:27:28.282: FINEST: Using open pooled cnx#0
2014-11-12 00:27:28.282: FINEST: Use connection #0
2014-11-12 00:27:28.283: FINE: Got cnx#0
2014-11-12 00:27:28.283: FINE: Got prepared query from cache in cnx#0 for: SELECT givenName, familyName FROM person
2014-11-12 00:27:28.283: FINEST: Release connection #0
2014-11-12 00:27:28.283: INFO: Got prepared query
2014-11-12 00:27:28.285: FINE: Prepare...
2014-11-12 00:27:28.285: FINE: Getting prepared query for: SELECT givenName, familyName FROM person
2014-11-12 00:27:28.286: FINEST: Getting a connection
2014-11-12 00:27:28.286: FINEST: Number of in-use connections: 0
2014-11-12 00:27:28.286: FINEST: Using open pooled cnx#0
2014-11-12 00:27:28.286: FINEST: Use connection #0
2014-11-12 00:27:28.286: FINE: Got cnx#0
2014-11-12 00:27:28.286: FINE: Got prepared query from cache in cnx#0 for: SELECT givenName, familyName FROM person
2014-11-12 00:27:28.286: FINE: Prepared, now to execute
2014-11-12 00:27:28.286: FINEST: About to execute
2014-11-12 00:27:28.286: FINE: sendBuffer header
2014-11-12 00:27:28.286: FINE: sending header, packet 0
2014-11-12 00:27:28.286: FINE: writeBuffer length=4
2014-11-12 00:27:28.286: FINE: _writeBuffer offset=0
2014-11-12 00:27:28.287: FINE: Wrote 4 bytes
2014-11-12 00:27:28.287: FINE:
0b 00 00 00                ····

2014-11-12 00:27:28.287: FINE: sendBuffer body, buffer length=11, start=0, len=11
2014-11-12 00:27:28.287: FINE: writeBuffer length=11
2014-11-12 00:27:28.287: FINE: _writeBuffer offset=0
2014-11-12 00:27:28.287: FINE: Wrote 0 bytes
2014-11-12 00:27:28.287: FINE:
17 01 00 00  00 00 01 00   ········
00 00 01                   ···

2014-11-12 00:27:28.290: FINE: error SocketException: Write failed, address = localhost, port = 44800
2014-11-12 00:27:28.290: FINEST: Release connection #0
2014-11-12 00:27:28.292: SEVERE: test: execute: SocketException: Write failed, address = localhost, port = 44800

Select behaviour

I downloaded the "latest" changes to the package and encountered a problem with my test program. Looking at the old and new example programs, the Select has altered.

I notice that you have a comment that something is no longer working (interleave), so I just wanted to know that this change (stream) is permanent, and could you give a brief explanation of the change and what impact it has?

Also, what is "broken" with the interleave test?

This is taken from your "old" example program.

pool.query('select p.id, p.name, p.age, t.name, t.species '
    'from people p '
    'left join pets t on t.owner_id = p.id').then((result) {
  print("got results");
  for (var row in result) {
    if (row[3] == null) {
      print("ID: ${row[0]}, Name: ${row[1]}, Age: ${row[2]}, No Pets");
    } else {
      print("ID: ${row[0]}, Name: ${row[1]}, Age: ${row[2]}, Pet Name: ${row[3]}, Pet Species ${row[4]}");
    }
  }
  completer.complete(null);

The "new" example

pool.query('select p.id, p.name, p.age, t.name, t.species '
    'from people p '
    'left join pets t on t.owner_id = p.id').then((result) {
  print("got results");
  result.stream.listen((row) {
    if (row[3] == null) {
      print("ID: ${row[0]}, Name: ${row[1]}, Age: ${row[2]}, No Pets");
    } else {
      print("ID: ${row[0]}, Name: ${row[1]}, Age: ${row[2]}, Pet Name: ${row[3]}, Pet Species ${row[4]}");
    }
  }, onDone: () {
    completer.complete(null);
  });
});

unable to catch exception where connection is made but mysql not running.

While testing error-handling in a test-program that I am writing that uses sqljocky, I have not been able to catch an error in the situation where a connection has been made however the Server is not running. After getting the connection, I test a query, and an unhandled exception is raised.

On running the example.dart program provided, I found that in the same situation, an unhandled exception is raised.

My example is probably a little convoluted and verbose now, however I think that it illustrates the problem. When running with MySql started, there is no error from my test program. However, if I run an invalid query, I also get an unhandled exception.

Example output when running test program (Server not started)
Testing sqljocky connection to Mysql
Database Connected
Testing Db Connection
Uncaught Error: SocketException: Connection failed (OS Error: No
connection could be made because the target machine actively 
refused it.
, errno = 10061), address = localhost, port = 3306
Stack Trace: .....

Example Test Program

import 'dart:io';
import 'dart:async' as async;
import 'package:sqljocky/sqljocky.dart';
import 'package:sqljocky/utils.dart';

ConnectionPool     ogDb;       // Database connection global object

main() {
  print ("Testing sqljocky connection to Mysql");

  /*
   * Connect to database
   */
  String sCheckpoint = "Connect to Database";  

  fConnectToDb().then((_) {

/*
 * Test Connection
 */
    print ("Testing Db Connection");
    return fTestDbConnection();
  })
  .catchError((oError) =>
    fFatal("Main", "Db not connected. Error = ${oError}"))
  .then((_) {    
    print("Database connection now tested");
    print("Closing database connection");
    fExit(0);
  })
  .catchError((oError) =>
    fFatal("Main", "Socket test error. Error = ${oError}"));  
}

/*
 * Connect To Database
 */
async.Future<bool> fConnectToDb() {
  async.Completer<bool> oCompleter = new async.Completer<bool>();

  try {
    ogDb = new ConnectionPool(
            host: "localhost", port: 3306, user: "admin",
            password: "admin", db: "test", max:1);

    print ("Database Connected");
    oCompleter.complete((ogDb != null)); 
    return oCompleter.future;
  } catch(oError) {
    String sErrorMsg = (oError is SocketException) ?
                        "Database is not connected" :
                        "Fatal error encountered ${oError}";
    fFatal("fConnectToDb", sErrorMsg);
  }
}

/*
 * Test Db Connection
 */
async.Future<bool> fTestDbConnection() {
  async.Completer<bool> oCompleter = new async.Completer<bool>();

  String sSql = "DROP TABLE IF EXISTS testConn001";

  var querier = new QueryRunner(ogDb, [sSql]);
  querier.executeQueries()
  .then((_) { oCompleter.complete(true); })
  .catchError((oError) =>
    fFatal("fTestDbConnection", "Error = ${oError}"));

  return oCompleter.future;
}  

/*
 * Fatal Error Encountered
 */
void fFatal(String sCheckpoint, String sError) {
  print ("Fatal error. ${sCheckpoint} : Error = $sError");
  print ("Program terminated");
  fExit(1);
}

/*
 *   Exit this program
 */
void fExit(int iCode) {
  if (ogDb != null)
    ogDb.close();

  exit(iCode);
}

Confirm this out of range bug doesn't exist.

I'm using 0.3.0 and this query:

SELECT body FROM node_revisions WHERE nid=1495 AND vid=1495

against this data:
http://d.pr/i/6qgU

Throws:

Uncaught Error: RangeError: index (1) must be in the range [0..1)
Unhandled exception:
RangeError: index (1) must be in the range [0..1)
#0      _FutureImpl._scheduleUnhandledError.<anonymous closure> (dart:async:347:9)
#1      Timer.Timer.<anonymous closure> (dart:async-patch:11:15)
#2      _Timer._createTimerHandler._handleTimeout (dart:io:6031:28)
#3      _Timer._createTimerHandler._handleTimeout (dart:io:6039:7)
#4      _Timer._createTimerHandler.<anonymous closure> (dart:io:6047:23)
#5      _ReceivePortImpl._handleMessage (dart:isolate-patch:40:92)

There's no way to catch it.

However: if I add "nid" to the list of selects:

SELECT nid, body FROM node_revisions WHERE nid=1495 AND vid=1495

Then it works.

Note: the specific row has empty body.

I'll try to test against latest version when I find time.

INSERT BLOB STOPS AFTER 151 CHAR.

My code is this:
Future UpdateBD(ConnectionPool cnxDB){
var completer = new Completer();
// On delete tout et on remet tout
cnxDB.prepare("DELETE FROM draw_text_zone WHERE draw_text_zone.id_draw = ${this.id_draw}").then((query) {
query.execute().then((result) {
if(list.length>0){
cnxDB.prepare("INSERT INTO draw_text_zone (id_draw, pen_style_style, pen_style_color, pen_style_background_color, pen_style_thickness, pen_style_filled, insertion_zone_x, insertion_zone_y, width_factor, text_height, italic, bold, mirrored_x, mirrored_y, justification, font_family, rotation_rad, height_zone, width_zone, text) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").then((query) {
List ListQuery = new List();
list.forEach((text_zone){
ListQuery.add(text_zone.getListQuery(this.id_draw));
});
//print(ListQuery);
query.executeMulti(ListQuery).then((result) {
completer.complete(result);
}).catchError((e){
print ("PB: execute insert text_zones, $e");
completer.complete(null);
});
}).catchError((e){
print ("PB: prepare insert text_zones, $e");
completer.complete(null);
});
}
else{
completer.complete(result);
}
}).catchError((e){
print ("PB: execute delete text_zones, $e");
completer.complete(null);
});
}).catchError((e){
print ("PB: prepare delete text_zones, $e");
completer.complete(null);
});
return completer.future;
}
and the 'text' is a text blob more than 2000 chars.
All is good with the sql request, but in the database, the text is cutted at 151 chars.
if i put manually a lot of chars in a blob, i can read it without problem.
I'am working with Windows 7, dart:24275, SQLJOCKY: 0.5.3.
Could you help me?
Thank you and best regards.
Bruno LE GUERNIC.

Error message - trying example

I'm very new to dart and programming and am getting the following error when running the example. Do you know what the problem may be? Hope I'm not doing something stupid with configuration data. Any help would be appreciated.

opening connection
connection open
running example
dropping tables
Uncaught Error: The null object does not have a getter 'length'.

NoSuchMethodError: method not found: 'length'
Receiver: null
Arguments: []
Stack Trace:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1 Utf8Encoder.convert (dart:convert/utf.dart:90)
#2 Codec.encode (dart:convert/codec.dart:22)
#3 _AuthHandler.createRequest (package:sqljocky/src/auth/auth_handler.dart:50:38)
#4 _handleData (package:sqljocky/src/connection.dart:184:43)
#5 _rootRunUnary (dart:async/zone.dart:730)
#6 _RootZone.runUnary (dart:async/zone.dart:864)
#7 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#8 _Future._propagateToListeners (dart:async/future_impl.dart:571)
#9 _Future._completeWithValue (dart:async/future_impl.dart:331)
#10 _Future._asyncComplete. (dart:async/future_impl.dart:393)
#11 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#12 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#13 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)

Unhandled exception:
The null object does not have a getter 'length'.

NoSuchMethodError: method not found: 'length'
Receiver: null
Arguments: []
#0 _rootHandleUncaughtError.. (dart:async/zone.dart:713)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#3 _asyncRunCallback (dart:async/schedule_microtask.dart:36)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)

Logging level

For some reason logging level for messages like "Running query: ..." is set to INFO. Is this behavior intentional? If no, could you fix it, please, or maybe I could create pull request.

Error when rolling back transaction after performing only a SELECT query

When I run this code:

Future _putMethod(RestRequest request) {
  return this._pool.startTransaction().then((mysql.Transaction tran) {
    return tran.prepare("SELECT * FROM files").then((mysql.Query query) {
      return query.execute().then((result) {
        // Do something?
      }).then((_) {
        this._log.info("Closing");
        query.close();
      });
    }).then((_) {
      this._log.info("Rolling");
      return tran.rollback().then((_) {
        this._log.info("Rolled");
      });
    });
  });
}

I get this output:

2014-07-04 14:35:46.528: INFO: (ConnectionPool) Starting transaction
2014-07-04 14:35:46.572: INFO: (FilesResource) Closing
2014-07-04 14:35:46.573: INFO: (FilesResource) Rolling
2014-07-04 14:35:46.574: SEVERE: (RestServer) MySQL Client Error: Connection #0 cannot process a request for Instance of '_QueryStreamHandler' while a request is already in progress for Instance of '_ExecuteQueryHandler'
Uncaught Error: Bad state: Future already completed
Stack Trace:
#0 _AsyncCompleter.completeError (dart:async/future_impl.dart:35)
#1 _handleData (package:sqljocky/src/connection.dart:211:31)
#2 _rootRunUnary (dart:async/zone.dart:730)
#3 _RootZone.runUnary (dart:async/zone.dart:864)
#4 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#5 _Future._propagateToListeners (dart:async/future_impl.dart:571)
#6 _Future._completeWithValue (dart:async/future_impl.dart:331)
#7 _Future._asyncComplete. (dart:async/future_impl.dart:393)
#8 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#9 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)

Am I doing something wrong?

Quick question regarding SELECT statements and prepared queries...

Hey, thanks for the great package first off however I am having a few issues with prepared statements.

I have made this test query:

String username = "Plornt"
db.prepare("SELECT name FROM `users` WHERE `name`=?").then((query) {
  return query.execute([username]);
}).then((res) { ... });

However it appears not to work and gives the error:

NoSuchMethodError: incorrect number of arguments passed to method named >'execute'
Receiver: Instance of 'Query'
Tried calling: execute(GrowableObjectArray len:1)
Found: execute()

Is there no way of binding parameters to a normal SELECT statement or am I doing this wrong?

French accents

I teach a course On Dart (http://ondart.me/). One of my students used the driver with data in French (e.g., department 'comptabilité'). He got the following errror:
AsyncError: 'Error 1366 (HY000): Incorrect string value: '\xE9' for column 'DEPARTEMENT' at row 1'.

Is that related to mysql or to the driver?

BLOB in prepared statements gets the length wrong...

in src/prepared_statements/binary_data_packet.dart

in the method _readFile on the FIELD_TYPE_BLOB section, you determine the length by a call to buffer.readByte, thats a mistake, since lengths of BLOB fields can be quite a large amount larger than a byte ;)

I have tested using buffer.readLengthCodeBinary() instead, and that seems to work better ;)

Bug in ConnectionPool._closeQuery

This code assumes it will get same connection in future callback (cnx), that it sent into _waitUntilReady:

_waitUntilReady(cnx).then((_) {
    _log.finest("Connection ready - closing query: ${q.sql}");
    var handler = new _CloseStatementHandler(preparedQuery.statementHandlerId);
    cnx.autoRelease = !retain;
    cnx.processHandler(handler, noResponse: true);
  });

but it gets another object (_), that has different data. In my case cnx._handler is not empty, so processHandler throws exception. But after _finishAndReuse (before future callback) _._handler becomes null and the state of _ is more likely ready for closing prepared query. So I would use _ in callback rather cnx.
I can send a pull request if I am right and there must _ instead of cnx.

new ConnectionPool fails silently

If invalid data is used to create a ConnectionPool the pool will be created but using it will always result in an "Illegal argument(s)" error. I think throwing some kind of exception here would make this issue easier to debug.

ConnectionPool connectionPool = new ConnectionPool(host: 'WRONGHOST', user: ...); connectionPool.query("SELECT 1;");

Pool running out of connections

Hi, I'm not sure if this is a problem with the library or how I use it.
When executing getUser which uses stream.single multiple times, everything works as expected. But when using getUser2 with stream.first or stream.elementAt(0) requests always get stuck when the maximum number of connections of the pool is reached and the pool does not return the results of other queries until you restart the application.

final String GET_USER_BY_ID = "SELECT * FROM users WHERE id = ?";

// Works as expected.
Future<Row> getUser(String userId) {
  return _pool.prepareExecute(GET_USER_BY_ID, [userId]).then((Results results) {
    return results.stream.single;
  });
}

// Stuck after 5th query (pool max).
Future<Row> getUser2(String userId) {
  return _pool.prepareExecute(GET_USER_BY_ID, [userId]).then((Results results) {
    return results.stream.first; // or results.stream.elementAt(0)
  });
}

main() {
  for (int i = 0; i<10; i++) {
    getUser2("1").then((row) => _logger.info("getUser2 - i=$i: Got row: $row"));
  }
}

Looking through the logs at Level.FINEST the connections seem to be released and reused, though - but the results never reach my code. Here is the log: http://pastebin.com/HM7W2Q4j

Not quite sure what to do with this.

Blob (list of int) read write problem

Hi,
When i read ( or write) a binary blob i have the error:
FormatException: Bad UTF-8 encoding 0xe3
Stack Trace:
#0 _Utf8Decoder.convert (dart:convert/utf.dart:455)
#1 Utf8Decoder.convert (dart:convert/utf.dart:322)
#2 Utf8Codec.decode (dart:convert/utf.dart:66)
#3 Blob.toString (package:sqljocky/src/blob.dart:30:23)
#4 _StringBase._interpolate (dart:core-patch/string_patch.dart:589)
#5 _ExecuteQueryHandler._writeBlob (package:sqljocky/src/prepared_statements/execute_query_handler.dart:137:28)
#6 _ExecuteQueryHandler._writeValue (package:sqljocky/src/prepared_statements/execute_query_handler.dart:54:19)
#7 _ExecuteQueryHandler.createRequest (package:sqljocky/src/prepared_statements/execute_query_handler.dart:30:18)
#8 _Connection.processHandler (package:sqljocky/src/connection.dart:290:38)
#9 Query._execute (package:sqljocky/src/query.dart:118:37)
#10 Query.executeMulti..executeQuery (package:sqljocky/src/query.dart:145:19)
#11 Query.executeMulti. (package:sqljocky/src/query.dart:161:21)
#12 _RootZone.runUnary (dart:async/zone.dart:1155)
#13 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484)
#14 _Future._propagateToListeners (dart:async/future_impl.dart:567)
#15 _Future._completeWithValue (dart:async/future_impl.dart:358)
#16 _Future._asyncComplete. (dart:async/future_impl.dart:412)
#17 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#18 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#19 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#20 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)
#0 _rootHandleUncaughtError. (dart:async/zone.dart:886)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#3 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)

I modified your sample like this.
Future createTables() {
print("creating tables");
var querier = new QueryRunner(pool, ['create table people (id integer not null auto_increment, '
'name varchar(255), '
'age integer, '
'primary key (id))',

                                    'create table pets (id integer not null auto_increment, '
                                    'name varchar(255), '
                                    'species text, '
                                    'infos blob,'
                                    'owner_id integer, '
                                    'primary key (id),'
                                    'foreign key (owner_id) references people (id))'
                                    ]);
print("executing queries");
return querier.executeQueries();

}
Future addData() {
var completer = new Completer();
pool.prepare("insert into people (name, age) values (?, ?)").then((query) {
print("prepared query 1");
var parameters = [
["Dave", 15],
["John", 16],
["Mavis", 93]
];
return query.executeMulti(parameters);
}).then((results) {
print("executed query 1");
return pool.prepare("insert into pets (name, species, infos , owner_id) values (?, ?, ?, ?)");
}).then((query) {
print("prepared query 2");
File FileDocDog= new File("dog.pdf");
File FileDocCow= new File("cow.jpg");
FileDocDog.readAsBytes().then((List innerFileDog){
FileDocCow.readAsBytes().then((List innerFileCow){
Blob blobDog = new Blob.fromBytes(innerFileDog);
Blob blobCow = new Blob.fromBytes(innerFileCow);
var parameters = [
["Rover", "Dog", blobDog ,1],
["Daisy", "Cow", blobCow , 2],
["Spot", "Dog", blobDog, 2]];
// ["Spot", "D\u0000og", 2]];
return query.executeMulti(parameters);
});
});
}).then((results) {
print("executed query 2");
completer.complete(null);
});
return completer.future;
}

I try also to read a blob, i have the same problem. ( I put the blob value with phpmyadmin)
Thank you.
Bruno LE GUERNIC.

Class '_ResultsImpl' has no instance getter 'iterator'.

test('Select all tasks', () {
pool.query(
'select t.title, t.completed, t.updated '
'from task t '
).then((result) {
print('selected all tasks');
for (var row in result) {
print(
'title: ${row[0]}, '
'completed: ${row[1]}, '
'updated: ${row[2]}'
);
}
});
});

produces

selected all tasks
Uncaught Error: Class '_ResultsImpl' has no instance getter 'iterator'.

NoSuchMethodError : method not found: 'iterator'
Receiver: Instance of '_ResultsImpl@0xf04aefa'
Arguments: []
Stack Trace:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:23:25)
#1 testTasks... (file:///home/dr/git/db/mysql_spirals/mysql_s00/task_mysql_test.dart:15:25)
#2 _ThenFuture._zonedSendValue (dart:async/future_impl.dart:371:24)
#3 _TransformFuture._sendValue. (dart:async/future_impl.dart:348:48)
#4 _ZoneBase._runInZone (dart:async/zone.dart:82:17)
#5 _ZoneBase._runUnguarded (dart:async/zone.dart:102:22)
#6 _ZoneBase.executeCallback (dart:async/zone.dart:58:23)
#7 _TransformFuture._sendValue (dart:async/future_impl.dart:348:26)
#8 _FutureImpl._setValueUnchecked (dart:async/future_impl.dart:184:26)
#9 _FutureImpl._asyncSetValue. (dart:async/future_impl.dart:218:25)
#10 _asyncRunCallback (dart:async/event_loop.dart:9:15)
#11 _createTimer. (dart:async-patch/timer_patch.dart:8:13)
#12 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:96:21)
#13 _Timer._createTimerHandler. (timer_impl.dart:112:23)
#14 _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

Unhandled exception:
Class '_ResultsImpl' has no instance getter 'iterator'.

NoSuchMethodError : method not found: 'iterator'
Receiver: Instance of '_ResultsImpl@0xf04aefa'
Arguments: []
#0 _DefaultZone.handleUncaughtError. (dart:async/zone.dart:146:7)
#1 _asyncRunCallback (dart:async/event_loop.dart:9:15)
#2 _asyncRunCallback (dart:async/event_loop.dart:13:7)
#3 _createTimer. (dart:async-patch/timer_patch.dart:8:13)
#4 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:96:21)
#5 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:104:7)
#6 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:104:7)
#7 _Timer._createTimerHandler. (timer_impl.dart:112:23)
#8 _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

File not found: connection.options, path =

I am using the latest version of sqljocky (0.5.7). I have created the 'connection.options' file by copying 'connection.options.example' and modifying the settings (not the first time user of sqljocky). The 'connection.options' file is in the same folder where the 'connection.options.example' is located.

When I run example/example.dart I get the following error:

Breaking on exception: FileException: File not found: connection.options, path =

Transactions

I like what I have seen of sqljocky and I would like to try it. I've run the example and looked at it. Do you have an example that uses eg. Start Transaction", Insert, Update, Commit, Rollback?

Windows7 sqljocky0.4.4 dart22879

What steps will reproduce the problem?
1.take the example on the web with people and pets at https://github.com/jamesots/sqljocky/blob/master/example/example.dart
2.run
3.
What is the expected output? What do you see instead?
print result
opening connection
connection open
running example
dropping tables
Uncaught Error: MySQL Client Error: Cannot read from socket, already reading
Stack Trace:
#0 _BufferedSocket.readBuffer (package:sqljocky/src/buffered_socket.dart:103:7)
#1 _Connection._handleHeader._handleHeader (package:sqljocky/src/connection.dart:96:23)
#2 _ThenFuture._sendValue (dart:async/future_impl.dart:265:24)
#3 _FutureImpl._setValue (dart:async/future_impl.dart:149:26)
#4 _AsyncCompleter._setFutureValue. (dart:async/future_impl.dart:29:23)
#5 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:15:17)
#6 Timer.run. (dart:async/timer.dart:17:21)
#7 Timer.Timer. (dart:async-patch/timer_patch.dart:9:15)

Unhandled exception:
MySQL Client Error: Cannot read from socket, already reading
#0 _FutureImpl._scheduleUnhandledError. (dart:async/future_impl.dart:180:9)
#1 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:15:17)
#2 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:25:9)
#3 Timer.run. (dart:async/timer.dart:17:21)
#4 Timer.run. (dart:async/timer.dart:25:13)
#5 Timer.Timer. (dart:async-patch/timer_patch.dart:9:15)
#6 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:99:28)
#7 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:107:7)
#8 _Timer._createTimerHandler. (timer_impl.dart:115:23)
#9 _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

What version of the product are you using? On what operating system?
sqljocky 0.4.4 EDITOR r22659

Please provide any additional information below.
before this version no problem.

Future already completed when reading long text blob.

My code is this:
class CDDrawingsS extends CDCDrawings{
ConnectionPool cnxDBDefault;
var completer;
CDDrawingsS(this.cnxDBDefault):super(){}

Future ImportFromBD(String Sql,ConnectionPool cnxDB){
completer = new Completer();
cnxDB.query(Sql).then((result) {
result.stream.listen(onMessageBD,onError:(e)=>onErrorBD(e),onDone: ()=>onDoneBD());
}).catchError((e) {
print("catchError; $e dans ${this.toString()}");
completer.complete(BW_NOK);
});
return completer.future;
}
onMessageBD(var row){
CDDrawingS NewD = new CDDrawingS.DB(row);
if(NewD.Id >0)//on ne veut pas du 0=null
CDDrawingsS:list.add(NewD);
print("TRACE: CDDrawingsS, ImportFromBD: $row");
}
onErrorBD(e){
print("onErrorBD; $e dans ${this.toString()}");
}
onDoneBD(){
completer.complete(BW_OK);
}
}
When I have a big text blob like this:
CREATE TABLE IF NOT EXISTS draw (
id_draw int(11) NOT NULL AUTO_INCREMENT,
name varchar(128) NOT NULL DEFAULT '1',
id_draw_type int(11) NOT NULL,
origine_x float NOT NULL DEFAULT '0',
origine_y float NOT NULL DEFAULT '0',
creation_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
svg_blob longtext NOT NULL,
PRIMARY KEY (id_draw),
UNIQUE KEY name_type (name,id_draw_type),
KEY id_draw_type (id_draw_type)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=378 ;
In my example svg_blob has 55605 characters.( I wrote it with your function)
I have the error:
Uncaught Error: Bad state: Future already completed
Stack Trace:
#0 _Completer.completeError (dart:async/future_impl.dart:20:22)
#1 _Connection._handleData._handleData (package:sqljocky/src/connection.dart:132:31)
#2 _ThenFuture._zonedSendValue (dart:async/future_impl.dart:355:24)
#3 _TransformFuture._sendValue. (dart:async/future_impl.dart:332:48)
#4 _ZoneBase._runInZone (dart:async/zone.dart:70:17)
#5 _ZoneBase._runUnguarded (dart:async/zone.dart:98:22)
#6 _ZoneBase.executeCallback (dart:async/zone.dart:56:23)
#7 _TransformFuture._sendValue (dart:async/future_impl.dart:332:26)
#8 _FutureImpl._setValue (dart:async/future_impl.dart:185:26)
#9 _AsyncCompleter._setFutureValue. (dart:async/future_impl.dart:40:23)
#10 _ZoneBase._runInZone (dart:async/zone.dart:78:19)
#11 _ZoneBase._runGuarded (dart:async/zone.dart:95:22)
#12 _ZoneBase.runAsync. (dart:async/zone.dart:104:18)
#13 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:9:15)
#14 _createTimer. (dart:async-patch/timer_patch.dart:8:13)

Unhandled exception:
false
#0 _DefaultZone.handleUncaughtError. (dart:async/zone.dart:148:7)
#1 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:9:15)
#2 _asyncRunCallback._asyncRunCallback (dart:async/event_loop.dart:13:7)
#3 _createTimer. (dart:async-patch/timer_patch.dart:8:13)
#4 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:91:28)
#5 _Timer._createTimerHandler._handleTimeout (timer_impl.dart:99:7)
#6 _Timer._createTimerHandler. (timer_impl.dart:107:23)
#7 _ReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:81:92)

My versions: Windows7: dart r24275 sqljocky: 0.5.4
Thank you for a look.

Uncaought Error: The null object does not have a method 'readBuffer'.

DB access worked already (great package BTW) but since today I get an exception - see below:
It might have been caused by Dart/package/MySQL updates/app code changes.
I worked on other parts of the app for a few days, and didn't run the part with DB access since.

The exception occurred first with the published package then
I changed my dependency to point to your Github repo, but that didn't change anything.

It's hard to debug because the DartEditor (Dart VM version: 1.3.0-dev.1.1 (Sun Mar 2 01:25:45 2014) on "linux_x64") I use currently doesn't highlight the correct line while debugging :-(
In the whole stack trace doesn't show a reference to my custom code so I thought I ask here ;-).

Any idea?

2014.47.04 15:47:33.261 bwu_entity_designer_server.db.mysql [FINE]: synchronizeSchema: schema: BWU_ENTITY_DESIGNER_MODEL
2014.47.04 15:47:33.277 bwu_entity_designer_server.db.mysql [FINE]: checkSchemaExists: schema: BWU_ENTITY_DESIGNER_MODEL
2014.47.04 15:47:34.716 Query   [FINE]: Getting prepared query for: SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?;
2014.47.04 15:47:34.718 ConnectionPool  [FINEST]:   Getting a connection
2014.47.04 15:47:34.722 ConnectionPool  [FINEST]:   Number of in-use connections: 0
2014.47.04 15:47:34.723 ConnectionPool  [FINEST]:   Creating new pooled cnx#0
2014.47.04 15:47:34.728 Connection.Lifecycle    [FINEST]:   Use connection #0
2014.47.04 15:47:34.731 Connection  [FINE]: opening connection to 127.0.0.1:3306/null
2014.47.04 15:47:34.783 BufferedSocket  [FINE]: READ data
2014.47.04 15:47:34.783 BufferedSocket  [FINE]: READ data: no buffer
2014.47.04 15:47:34.783 Connection  [FINE]: readPacket readyForHeader=true
2014.47.04 15:47:39.853 BufferedSocket  [FINE]: WRITE data
Uncaught Error: The null object does not have a method 'readBuffer'.

NoSuchMethodError: method not found: 'readBuffer'
Receiver: null
Arguments: [Instance of 'Buffer']
Stack Trace: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1      _readPacket (package:sqljocky/src/connection.dart:119:25)
#2      _onData (package:sqljocky/src/buffered_socket.dart:81:22)
#3      _rootRunUnary (dart:async/zone.dart:717)
#4      _RootZone.runUnary (dart:async/zone.dart:854)
#5      _BaseZone.runUnaryGuarded (dart:async/zone.dart:569)
#6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:333)
#7      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263)
#8      _StreamController&&_SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:529)
#9      _StreamController._add (dart:async/stream_controller.dart:438)
#10     _StreamController.add (dart:async/stream_controller.dart:395)
#11     _RawSocket._RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:987)
#12     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:580)
#13     _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#14     _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#15     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)


Unhandled exception:
The null object does not have a method 'readBuffer'.

NoSuchMethodError: method not found: 'readBuffer'
Receiver: null
Arguments: [Instance of 'Buffer']
#0      _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:700)
#1      _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#3      _asyncRunCallback (dart:async/schedule_microtask.dart:36)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)

preparedExecute not populating row names like query

I was using preparedExecute in my code, and was confused when i took a look at the row items returned from queries, so i wrote a new testcase for it in integration/row.dart

So mine now looks like this...


part of integrationtests;

void runRowTests(String user, String password, String db, int port, String host) {
  ConnectionPool pool;
  group('row tests:', () {
    test('setup', () {
      pool = new ConnectionPool(user:user, password:password, db:db, port:port, host:host, max:1);
      return setup(pool, "row", "create table row (id integer, name text, " 
        "`the field` text, length integer)");
    });

    test('store data', () {
      var c = new Completer();
      pool.prepare('insert into row (id, name, `the field`, length) values (?, ?, ?, ?)').then((query) {
        query.execute([0, 'Bob', 'Thing', 5000]).then((Results results) {
          c.complete();
        });
      });
      return c.future;
    });

    test('select from stream using query and listen', () {
      var futures = [];
      for (var i = 0; i < 5; i++) {
        var c = new Completer();
        pool.query('select * from row').then((Results results) {
          results.listen((row) {
            expect(row.id, equals(0));
            expect(row.name.toString(), equals("Bob"));
            // length is a getter on List, so it isn't mapped to the result field
            expect(row.length, equals(4));
          }, onDone: () {
            c.complete();
          });
        });
        futures.add(c.future);
      }
      return Future.wait(futures);
    });

    test('select from stream using prepareExecute and listen', () {
      var futures = [];
      for (var i = 0; i < 5; i++) {
        var c = new Completer();
        pool.prepareExecute('select * from row where id = ?',[0]).then((Results results) {
          results.listen((row) {
            expect(row.id, equals(0));
            expect(row.name.toString(), equals("Bob"));
            // length is a getter on List, so it isn't mapped to the result field
            expect(row.length, equals(4));
          }, onDone: () {
            c.complete();
          });
        });
        futures.add(c.future);
      }
      return Future.wait(futures);
    });

    test('close connection', () {
      pool.close();
    });
  });
}

Am I right in assuming that this should pass?

It fails

Class '_BinaryDataPacket' has no instance getter 'id'.

Prepared statements and null values

Hey, not sure if this is already implemented but I couldnt get it to work. Basically if you create a prepared insert statement then try to make one of the parameters "null" it ignores the null values and then mixes up your insert statement parameters.

For example:

  static Future databaseCreate (ConnectionPool db, int funds, {int classID, int countryID, int formationID, int teamID, int isAI, int rank}) {
   return db.prepare("INSERT INTO `player` (funds, classID, countryID, formationID, teamID, isAI, rank) VALUES (?, ?, ?, ?, ?, ?, ?)")
            .then((query) { 
              query[0] = funds; ...etc
              return query.execute();
            });
  }

And then try to call that with some of the parameters being null (required if you use foreign key restraints else it creates an error) it ignores the nulls and inserts the rest of the fields into the wrong place.

How to handle/close pool/pools?

Hey :)

I develop the Dartabase tools
Model https://github.com/HannesRammer/Dartabase/tree/master/dartabase_model
and
Migration https://github.com/HannesRammer/Dartabase/tree/master/dartabase_migration
using your package.

I have multiple connection pools running at the same time,basically I am creating a pool each time I call the db.

Is there a way to close a single pool after the query is done? or is my approach not the right one

findPool.query.then((result){
  results.listen((row) {
       //update object with information 1
       findPool1.query.then((result){  
         //update object with information 2
         findPool1.close();
       });
   }).asFuture().then((_){
       findPool.close(); // but here findPool will be already closed from findPool1.close()
       completer.complete(object); //return object
      });
});

1.multiple pools?
yes or no

on yes
1.1.should we close pools?

I was thinking, I should create a pool only when someone hits save/load.
but then I cant close them, and then i am thinking .. after running a few minutes there must be like x many pools running?

on no
1.2.should we only keep only one pool for the dart server while the program is executed?
and everyone would have to query via this single pool!?

would we then still have to close the pool at the end of the connection and what if with one pool the max connections are reached?

query.executeMulti closes transaction connection

I'm working on a web service that will need to handle many concurrent requests. While executing a long-running process that makes use of a transaction, I tested running separate requests against the server. I found that occasionally I would get an sql error claiming that the connection being used to prepare/execute a query was already occupied preparing/executing a query. I turned up the logging to finest and discovered that both requests were using connection 0, which caused the two processes to conflict when the timing was right. I put a break point on the connection object's release function, and found that it was being called in the long-running process when a call to a query's executeMulti function was called. It appears that executeMulti releases the connection when it's done, without regard to whether it's in a transaction or not:

  Future<List<Results>> executeMulti(List<List> parameters) {
    return _prepare(true)
      .then((preparedQuery) {
        var c = new Completer<List<Results>>();
        _log.fine("Prepared query for multi execution. Number of values: ${parameters.length}");
        var resultList = new List<Results>();

        executeQuery(int i) {
          _log.fine("Executing query, loop $i");
          _execute(preparedQuery, parameters[i], retainConnection: true)
            .then((Results results) {
              _log.fine("Got results, loop $i");
              resultList.add(results);
              if (i < parameters.length - 1) {
                executeQuery(i + 1);
              } else {
                preparedQuery.cnx.release();
                c.complete(resultList);
              }
            })
            .catchError((e) {
              _releaseReuseCompleteError(preparedQuery.cnx, c, e);
            });
        }

        executeQuery(0);
        return c.future;
      });
  }

I switched my code to just loop the args over the regular query.execute, and I started seeing the second process use a connection 1 instead of 0, so that took care of it for me. Not a huge deal to work around, but this should probably be addressed.

query does not complete

After a few consecutive query's, the Future does not complete nor does an error occur

sqljocky version: 0.6.1
mysql version: mysql-5.6.14-osx10.7-x86_64
os: osx 10.8.5
dart SDK version: 0.8.7.0_r29341
dart EDITOR version: 0.8.7.0_r29341

any more info needed?

edit: this happens when no data is returned ie there is no id=2

    _connection.query(queryCompiler.compile()).then((results){
        results.stream.listen((List<dynamic> row) {
            print("foo");

            completer.complete(this);
        });
    }, onError: (e, s){
        print(e.toString());

        completer.completeError(e, s);
    });

Bad state: Cannot write to socket, it is closed on query close

I am getting this exception when I close the pool very soon after closing a query:

    Uncaught Error: Bad state: Cannot write to socket, it is closed
    Stack Trace: 
    #0      BufferedSocket.writeBufferPart (package:sqljocky/src/buffered_socket.dart:114:7)
    #1      BufferedSocket.writeBuffer (package:sqljocky/src/buffered_socket.dart:108:27)
    #2      _Connection._sendBufferPart (package:sqljocky/src/connection.dart:261:31)
    #3      _Connection._sendBuffer (package:sqljocky/src/connection.dart:249:29)
    #4      _Connection.processHandler (package:sqljocky/src/connection.dart:289:16)
    #5      ConnectionPool._closeQuery.<anonymous closure> (package:sqljocky/src/connection_pool.dart:220:29)
    #6      _rootRunUnary (dart:async/zone.dart:730)
    #7      _RootZone.runUnary (dart:async/zone.dart:864)
    #8      _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
    #9      _Future._propagateToListeners (dart:async/future_impl.dart:571)
    #10     _Future._completeWithValue (dart:async/future_impl.dart:331)
    #11     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:393)
    #12     _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
    #13     _asyncRunCallback (dart:async/schedule_microtask.dart:32)
    #14     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)


    Unhandled exception:
    Bad state: Cannot write to socket, it is closed
    #0      _rootHandleUncaughtError.<anonymous closure>.<anonymous closure> (dart:async/zone.dart:713)
    #1      _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
    #2      _asyncRunCallback (dart:async/schedule_microtask.dart:32)
    #3      _asyncRunCallback (dart:async/schedule_microtask.dart:36)
    #4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)

the issue seems to be that the query close fires of a Future internally, so the close() function returns before the close is actually finished:

void _closeQuery(Query q, bool retain) {
  _log.finest("Closing query: ${q.sql}");
  for (var cnx in _pool) {
    var preparedQuery = cnx.removePreparedQueryFromCache(q.sql);
    if (preparedQuery != null) {
        _waitUntilReady(cnx).then((_) {
        _log.finest("Connection ready - closing query: ${q.sql}");
        var handler = new _CloseStatementHandler(preparedQuery.statementHandlerId);
        cnx.autoRelease = !retain;
        cnx.processHandler(handler, noResponse: true);
      });
    }
  }
}

The pool close happens immediately, it closes the socket right away. This means the query close (which is delayed till after the pool close due to the Future) fails, unable to send whatever information it needs to through the socket. I think the query close either needs to be changed to return a Future that doesn't complete until the query is actually closed, or the query close needs to be changed to be able to deal with the closed socket.

Code to replicate the issue:

Future _putMethod(RestRequest request) {
  return new Future.sync(() {
    mysql.ConnectionPool pool = getConnectionPool();
      return pool.prepare("SELECT * FROM files").then((mysql.Query query) {
        return query.execute().then((result) {
          // Do something?
        }).then((_) {
          this._log.info("Closing");
          query.close();
        });
      }).then((_) {
        pool.close();
      });
  });
}

Extremely Slow on 64-bit Ubuntu 13.04

I wrote some test software using Dart and sqljocky on Windows 7, and all appeared to be working OK. I then transferred it to Ubuntu Linux 13.04 64bit, and it is taking at least 50-times longer to handle inserts and updates (sole user, small database). The Dart-Editor is 26106. The laptop that I am using for Ubuntu is about twice the speed of the Windows laptop. Dart in general I thought responded very quickly when initializing and starting on Ubuntu. The version of MySql is the one supplied by Ubuntu (5.5.32). I am using v0.5.8 of sqljocky. I have only just set up the laptop to run Ubuntu and Dart Editor. The results that I get are the same within the Editor and from the Command-Line. I'm not sure where to look to attempt to resolve. I presume that you know results from both Linux and Windows for comparison.

Fix published sqljocky for latest SDK

Latest SDK uses typed_data, not typeddata. Need to create a branch to fix this in and pub it, since trunk is currently incompatible with the pubbed version. People using the pubbed version are going to have to change their code eventually, but I might as well make sure I have the API just right before breaking their code again.

The built-in library 'dart:io' is not available on Dartium.

I wanted to use mysql with a basic select but seems having a permission error.
I am on Mac Mavericks.

2014-02-27 13:37:16.317 Chromium Helper[1567:507] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x602b, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
2014-02-27 13:37:16.650 Chromium Helper[1569:507] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x6327, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.

Document was loaded from Application Cache with manifest https://www.google.com.ph/_/chrome/newtab/manifest?espv=2&ie=UTF-8
Application Cache Checking event
2014-02-27 13:37:17.243 Chromium Helper[1571:507] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x6127, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.

The built-in library 'dart:io' is not available on Dartium.

sqljocky blocks until a connection is available

I was trying out sqljocky for a small project, to try and see if it was worth using Dart instead of NodeJS.

The setup was as follows:
-A Dart HttpServer was running on localhost, and requests queried a MySQL database. It was running on Windows.
-The database was present on an Ubuntu Server virtual machine.
-sqljocky was configured to target MySQL running on such vm.

Everything was fine, until the day which I turned off the VM and made a request to the server, to see what happened if the db couldn't be reached.

What happened was that the first request came and sqljocky started querying the db, but until that connection attempt times out, no more requests were treated by the HttpServer, even if they weren't dependent on the db.

In NodeJS's MySQL connector, even if the db can't be reached, subsequent requests are treated asynchronously.

Here's an excerpt of my code (could be me screwing up!), starting with the code that queries the db:

// Create a connection pool to handle DB queries.
_sql.ConnectionPool _pool = new _sql.ConnectionPool(
  host: '192.168.56.101',
  user: 'psiapp',
  password: '**redacted**',
  db: 'letrinhas'
);

/// Fetches tests from the database, and returns them as a [Map].
_async.Future<Map<String, dynamic>> getTestsFromDb() {
  return _pool.query('SELECT * FROM Testes;')
      .then((results) => results.toList())
      .then((rows) {
        var data = <String, dynamic> {
          'tests': <Map<String, dynamic>>[],
          'success': 1
        };

        // For each row, we'll add a new test
        // object to the test list.
        data['tests'] = rows.map((row) => {
          // Whatever
        }).toList(growable: false);

        return data;
      })
      .catchError((e) {
        _printError(e);
        return <String, dynamic> {
          'tests': [],
          'success': 0
        };
      });
}

And finally, the code for the HttpServer:

void startServer() {
  _io.HttpServer.bind('0.0.0.0', 8080).then((server) {
    server.listen(_handleRequest);
  });

  print('Server running on 0.0.0.0:8080');
}

void _handleRequest(_io.HttpRequest req) {
  var formattedDate = formatDate();
  // Even if the db connection wasn't working, the server should at least print this if a new request came.
  print('[$formattedDate] Got a ${req.method} request to ${req.uri.path} from ${req.connectionInfo.remoteAddress.address}');

  if (req.method == 'POST') {
    // Handle POST requests.

    switch (req.requestedUri.path) {
      case '/postTestResults':
        // Whatever
    }
  } else if (req.method == 'GET') {
    switch (req.requestedUri.path) {
      case '/testList':
        _fetchTests(req);
        break;
      default:
        _sendNotFound(req);
    }
  } else {
    // If we got this far, it means something went wrong.
    _sendNotFound(req);
  }
}

void _fetchTests(_io.HttpRequest req) {
  tasks.getTestsFromDb()
      .then((data) {
        req.response.write(_convert.JSON.encode(data));
        req.response.close();

        print('[${formatDate()}]Sent results to the client!');
      });
}

integration test on windows 7 with mysql 5.6 fails

Uncaught Error: Error 1292 (22007): Incorrect date value: '' for column 'adate' at row 1
Unhandled exception:
Error 1292 (22007): Incorrect date value: '' for column 'adate' at row 1
#0 _FutureImpl._scheduleUnhandledError. (dart:async:391:9)
#1 Timer.run. (dart:async:2362:21)
#2 Timer.run. (dart:async:2370:13)
#3 Timer.Timer. (dart:async-patch:15:15)
#4 _Timer._createTimerHandler._handleTimeout (dart:io:6385:28)
#5 _Timer._createTimerHandler._handleTimeout (dart:io:6393:7)
#6 _Timer._createTimerHandler. (dart:io:6401:23)
#7 _ReceivePortImpl._handleMessage (dart:isolate-patch:81:92)

Error "'Utf8Codec' is not loaded" after upgrading to 0.5.5

Just updated sqljocky package to version 0.5.5.

Opened pubspec.yaml
Edited version to 0.5.5 (was any)
Run Pub install
After sqlkocy updated changed version to any

App fails with run-time error:

'package:sqljocky/src/buffer.dart': Error: line 23 pos 34: type 'Utf8Codec' is not loaded
final Utf8Codec _codec = const Utf8Codec();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.