or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

clustering.mdconnection.mdindex.mdpooling.mdqueries.mdsecurity.md

queries.mddocs/

0

# Query Execution

1

2

Comprehensive query execution system supporting parameterized queries, streaming results, and event-driven processing. Includes full transaction support, prepared statements, and advanced query options for optimal performance and security.

3

4

## Capabilities

5

6

### Create Query

7

8

Creates a new query object for execution.

9

10

```javascript { .api }

11

/**

12

* Create a new Query instance

13

* @param {string} sql - The SQL for the query

14

* @param {array} [values] - Any values to insert into placeholders in sql

15

* @param {function} [callback] - The callback to use when query is complete

16

* @returns {Query} New query object

17

*/

18

function createQuery(sql, values, callback);

19

20

// Query options object

21

interface QueryOptions {

22

sql: string; // SQL query string

23

values?: any[]; // Parameter values for placeholders

24

timeout?: number; // Query timeout in milliseconds

25

nestTables?: boolean | string; // Nest result tables by table name

26

typeCast?: boolean | function; // Enable/disable or custom type casting

27

}

28

```

29

30

**Usage Examples:**

31

32

```javascript

33

const mysql = require('mysql');

34

35

// Create query with SQL string

36

const query1 = mysql.createQuery('SELECT * FROM users');

37

38

// Create query with parameters

39

const query2 = mysql.createQuery('SELECT * FROM users WHERE id = ?', [1]);

40

41

// Create query with callback

42

const query3 = mysql.createQuery('SELECT * FROM users', (error, results) => {

43

if (error) throw error;

44

console.log(results);

45

});

46

47

// Create query with options object

48

const query4 = mysql.createQuery({

49

sql: 'SELECT * FROM users WHERE active = ?',

50

values: [true],

51

timeout: 30000,

52

nestTables: true

53

});

54

```

55

56

### Query Execution Methods

57

58

Queries can be executed using connections, pools, or directly on query objects.

59

60

#### Connection Query

61

62

Execute query on a specific connection.

63

64

```javascript { .api }

65

/**

66

* Executes a SQL query on connection

67

* @param {string|object} sql - SQL query string or query object

68

* @param {array} [values] - Parameter values for prepared statements

69

* @param {function} [callback] - Callback function (err, results, fields)

70

* @returns {Query} Query object for event-based processing

71

*/

72

connection.query(sql, values, callback);

73

```

74

75

#### Pool Query

76

77

Execute query using pool connection.

78

79

```javascript { .api }

80

/**

81

* Executes query using pool connection

82

* @param {string|object} sql - SQL query string or query object

83

* @param {array} [values] - Parameter values for prepared statements

84

* @param {function} [callback] - Callback function (err, results, fields)

85

* @returns {Query} Query object for event-based processing

86

*/

87

pool.query(sql, values, callback);

88

```

89

90

**Basic Query Examples:**

91

92

```javascript

93

// Simple SELECT query

94

connection.query('SELECT * FROM users', (error, results, fields) => {

95

if (error) throw error;

96

console.log('Users:', results);

97

console.log('Field info:', fields);

98

});

99

100

// Parameterized query (prevents SQL injection)

101

connection.query('SELECT * FROM users WHERE id = ? AND active = ?', [userId, true], (error, results) => {

102

if (error) throw error;

103

console.log('User:', results[0]);

104

});

105

106

// INSERT query

107

connection.query('INSERT INTO users SET ?', {

108

name: 'John Doe',

109

email: 'john@example.com',

110

active: true

111

}, (error, results) => {

112

if (error) throw error;

113

console.log('Inserted user with ID:', results.insertId);

114

});

115

116

// UPDATE query

117

connection.query('UPDATE users SET ? WHERE id = ?', [{name: 'Jane Doe'}, userId], (error, results) => {

118

if (error) throw error;

119

console.log('Updated rows:', results.affectedRows);

120

});

121

122

// DELETE query

123

connection.query('DELETE FROM users WHERE id = ?', [userId], (error, results) => {

124

if (error) throw error;

125

console.log('Deleted rows:', results.affectedRows);

126

});

127

```

128

129

### Advanced Query Options

130

131

#### Nested Tables

132

133

Organize results by table name when joining multiple tables.

134

135

```javascript { .api }

136

// Query with nested tables

137

connection.query({

138

sql: 'SELECT u.*, p.* FROM users u LEFT JOIN profiles p ON u.id = p.user_id',

139

nestTables: true

140

}, (error, results) => {

141

if (error) throw error;

142

143

results.forEach(row => {

144

console.log('User:', row.u); // User table data

145

console.log('Profile:', row.p); // Profile table data

146

});

147

});

148

149

// Nested tables with separator

150

connection.query({

151

sql: 'SELECT u.*, p.* FROM users u LEFT JOIN profiles p ON u.id = p.user_id',

152

nestTables: '_'

153

}, (error, results) => {

154

if (error) throw error;

155

156

results.forEach(row => {

157

// Fields will be named like: u_id, u_name, p_bio, etc.

158

console.log(row);

159

});

160

});

161

```

162

163

#### Type Casting

164

165

Control how MySQL types are converted to JavaScript types.

166

167

```javascript { .api }

168

// Disable type casting (return raw buffer data)

169

connection.query({

170

sql: 'SELECT * FROM users',

171

typeCast: false

172

}, (error, results) => {

173

if (error) throw error;

174

console.log(results); // Raw buffer data

175

});

176

177

// Custom type casting function

178

connection.query({

179

sql: 'SELECT * FROM users',

180

typeCast: function (field, next) {

181

if (field.type === 'TINY' && field.length === 1) {

182

return (field.string() === '1'); // Convert TINYINT(1) to boolean

183

}

184

if (field.type === 'DATETIME') {

185

return new Date(field.string()); // Convert to Date object

186

}

187

return next(); // Use default type casting

188

}

189

}, (error, results) => {

190

if (error) throw error;

191

console.log(results);

192

});

193

```

194

195

#### Query Timeout

196

197

Set timeout for individual queries.

198

199

```javascript { .api }

200

connection.query({

201

sql: 'SELECT * FROM large_table',

202

timeout: 30000 // 30 seconds

203

}, (error, results) => {

204

if (error) {

205

if (error.code === 'PROTOCOL_SEQUENCE_TIMEOUT') {

206

console.error('Query timed out');

207

}

208

throw error;

209

}

210

console.log(results);

211

});

212

```

213

214

### Event-Driven Query Processing

215

216

Queries return EventEmitter objects for advanced result handling.

217

218

#### Query Events

219

220

```javascript { .api }

221

// Query event handlers

222

const query = connection.query('SELECT * FROM users');

223

224

query.on('result', (row, index) => {

225

console.log('Row %d:', index, row);

226

});

227

228

query.on('fields', (fields, index) => {

229

console.log('Fields for result set %d:', index, fields);

230

});

231

232

query.on('error', (err) => {

233

console.error('Query error:', err);

234

});

235

236

query.on('end', () => {

237

console.log('Query completed');

238

});

239

```

240

241

**Large Result Set Handling:**

242

243

```javascript

244

const query = connection.query('SELECT * FROM large_table');

245

246

let rowCount = 0;

247

248

query.on('result', (row) => {

249

// Pause connection to prevent memory overflow

250

connection.pause();

251

252

rowCount++;

253

254

// Process row asynchronously

255

processRow(row, () => {

256

// Resume connection after processing

257

connection.resume();

258

});

259

});

260

261

query.on('end', () => {

262

console.log('Processed %d rows', rowCount);

263

});

264

265

function processRow(row, callback) {

266

// Simulate async processing

267

setTimeout(() => {

268

console.log('Processed row:', row.id);

269

callback();

270

}, 10);

271

}

272

```

273

274

### Streaming Query Results

275

276

Convert query results to readable streams for memory-efficient processing.

277

278

```javascript { .api }

279

/**

280

* Returns query results as a readable stream

281

* @param {object} [options] - Stream options

282

* @param {number} [options.highWaterMark] - Stream buffer size (default: 16)

283

* @param {string} [options.encoding] - Stream encoding (default: null)

284

* @param {boolean} [options.objectMode] - Object mode (default: true for MySQL streams)

285

* @returns {ReadableStream} Readable stream of query results

286

*/

287

query.stream(options);

288

289

// Stream options interface

290

interface StreamOptions {

291

highWaterMark?: number; // Buffer size for stream backpressure control

292

encoding?: string; // Stream encoding (usually null for object streams)

293

objectMode?: boolean; // Whether stream operates in object mode

294

}

295

```

296

297

**Streaming Example:**

298

299

```javascript

300

const query = connection.query('SELECT * FROM large_table');

301

const stream = query.stream({highWaterMark: 5});

302

303

stream.on('data', (row) => {

304

console.log('Stream row:', row);

305

});

306

307

stream.on('end', () => {

308

console.log('Stream ended');

309

});

310

311

stream.on('error', (err) => {

312

console.error('Stream error:', err);

313

});

314

```

315

316

### Prepared Statements

317

318

MySQL package supports prepared statements through parameterized queries.

319

320

```javascript { .api }

321

// Prepared statement with single parameter

322

const stmt1 = 'SELECT * FROM users WHERE id = ?';

323

connection.query(stmt1, [userId], callback);

324

325

// Prepared statement with multiple parameters

326

const stmt2 = 'SELECT * FROM users WHERE age > ? AND city = ?';

327

connection.query(stmt2, [25, 'New York'], callback);

328

329

// Prepared statement with object parameters

330

const stmt3 = 'INSERT INTO users SET ?';

331

connection.query(stmt3, [{name: 'John', email: 'john@example.com'}], callback);

332

333

// Prepared statement with mixed parameters

334

const stmt4 = 'UPDATE users SET ? WHERE id = ?';

335

connection.query(stmt4, [{name: 'Jane'}, userId], callback);

336

```

337

338

### Multiple Statements

339

340

Execute multiple SQL statements in a single query (requires `multipleStatements: true`).

341

342

```javascript { .api }

343

// Enable multiple statements in connection config

344

const connection = mysql.createConnection({

345

host: 'localhost',

346

user: 'root',

347

password: 'password',

348

database: 'mydb',

349

multipleStatements: true

350

});

351

352

// Execute multiple statements

353

connection.query('SELECT 1; SELECT 2; SELECT 3', (error, results) => {

354

if (error) throw error;

355

356

console.log('First result:', results[0]); // SELECT 1 results

357

console.log('Second result:', results[1]); // SELECT 2 results

358

console.log('Third result:', results[2]); // SELECT 3 results

359

});

360

```

361

362

### Query Properties and Methods

363

364

```javascript { .api }

365

// Query instance properties

366

interface Query extends EventEmitter {

367

sql: string; // SQL query string

368

values: any[]; // Parameter values

369

370

// Methods

371

stream(options?: StreamOptions): ReadableStream;

372

}

373

374

// Query result structure

375

interface QueryResult {

376

// For SELECT queries

377

results?: any[]; // Result rows

378

fields?: FieldInfo[]; // Field metadata

379

380

// For INSERT queries

381

insertId?: number; // Auto-increment ID of inserted row

382

affectedRows?: number; // Number of affected rows

383

384

// For UPDATE/DELETE queries

385

affectedRows?: number; // Number of affected rows

386

changedRows?: number; // Number of actually changed rows

387

388

// General properties

389

fieldCount?: number; // Number of fields

390

serverStatus?: number; // Server status flags

391

warningCount?: number; // Number of warnings

392

message?: string; // Server message

393

}

394

395

// Field information

396

interface FieldInfo {

397

catalog: string; // Catalog name

398

db: string; // Database name

399

table: string; // Table name

400

orgTable: string; // Original table name

401

name: string; // Column name

402

orgName: string; // Original column name

403

charsetNr: number; // Character set number

404

length: number; // Column length

405

type: number; // Column type (see Types constants)

406

flags: number; // Column flags

407

decimals: number; // Decimal places

408

default?: any; // Default value

409

zeroFill: boolean; // Zero fill flag

410

protocol41: boolean; // Protocol 4.1 flag

411

}

412

```

413

414

### Transaction Queries

415

416

Queries within transactions follow the same patterns but require proper transaction management.

417

418

```javascript { .api }

419

function performTransaction(callback) {

420

connection.beginTransaction((err) => {

421

if (err) return callback(err);

422

423

// First query

424

connection.query('INSERT INTO users SET ?', {name: 'John'}, (error, results) => {

425

if (error) {

426

return connection.rollback(() => {

427

callback(error);

428

});

429

}

430

431

const userId = results.insertId;

432

433

// Second query

434

connection.query('INSERT INTO profiles SET ?', {user_id: userId, bio: 'Developer'}, (error, results) => {

435

if (error) {

436

return connection.rollback(() => {

437

callback(error);

438

});

439

}

440

441

// Commit transaction

442

connection.commit((err) => {

443

if (err) {

444

return connection.rollback(() => {

445

callback(err);

446

});

447

}

448

449

callback(null, {userId, profileId: results.insertId});

450

});

451

});

452

});

453

});

454

}

455

```

456

457

### Query Best Practices

458

459

1. **Parameterized Queries**: Always use parameterized queries to prevent SQL injection

460

2. **Error Handling**: Implement comprehensive error handling for all query types

461

3. **Connection Management**: Release connections promptly after query completion

462

4. **Large Results**: Use streaming or pagination for large result sets

463

5. **Timeouts**: Set appropriate query timeouts for long-running operations

464

6. **Type Casting**: Use custom type casting for application-specific data transformations

465

7. **Transaction Management**: Always handle transaction rollback scenarios

466

8. **Memory Management**: Pause connections when processing large result sets to prevent memory issues