or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-manipulation.mddatabase-management.mdindex.mdquerying-filtering.mdutility-functions.md

data-manipulation.mddocs/

0

# Data Manipulation

1

2

Methods for modifying, sorting, and transforming query results, including updates, deletions, data aggregation, and result processing.

3

4

## Capabilities

5

6

### Data Modification

7

8

Update or remove records based on query results with event callback support.

9

10

```javascript { .api }

11

/**

12

* Update records in the query result set

13

* @param changes - Object containing field updates

14

* @param runEvent - Whether to trigger event callbacks (default: true)

15

* @returns Updated QueryResult

16

*/

17

update(changes: object, runEvent?: boolean): QueryResult;

18

19

/**

20

* Remove records in the query result set

21

* @param runEvent - Whether to trigger event callbacks (default: true)

22

* @returns QueryResult (empty after removal)

23

*/

24

remove(runEvent?: boolean): QueryResult;

25

```

26

27

**Usage Examples:**

28

29

```javascript

30

// Update single field

31

db({ id: 1 }).update({ price: 199.99 });

32

33

// Update multiple fields

34

db({ category: "electronics" }).update({

35

discount: 0.15,

36

sale: true,

37

updated: new Date()

38

});

39

40

// Update with event callbacks disabled

41

db({ status: "pending" }).update({ status: "processed" }, false);

42

43

// Remove records

44

db({ expired: true }).remove();

45

46

// Remove with callback events disabled

47

db({ temporary: true }).remove(false);

48

49

// Chain updates

50

db({ department: "Sales" })

51

.filter({ performance: { lt: 2.0 } })

52

.update({ needsTraining: true, reviewed: new Date() });

53

```

54

55

### Result Retrieval

56

57

Get query results in various formats for data processing and analysis.

58

59

```javascript { .api }

60

/**

61

* Get all records as a plain JavaScript array

62

* @returns Array of record objects

63

*/

64

get(): object[];

65

66

/**

67

* Get the first record from the result set

68

* @returns First record object or false if empty

69

*/

70

first(): object | false;

71

72

/**

73

* Get the last record from the result set

74

* @returns Last record object or false if empty

75

*/

76

last(): object | false;

77

78

/**

79

* Get the count of records in the result set

80

* @returns Number of records

81

*/

82

count(): number;

83

84

/**

85

* Convert query results to JSON string

86

* @returns JSON string representation of results

87

*/

88

stringify(): string;

89

```

90

91

**Usage Examples:**

92

93

```javascript

94

// Get all matching records

95

const activeUsers = db({ active: true }).get();

96

console.log('Found', activeUsers.length, 'active users');

97

98

// Get single records (returns false if no results)

99

const firstUser = db().order("created").first();

100

const lastUser = db().order("created").last();

101

const newestUser = db().order("created desc").first();

102

103

// Check if results exist

104

if (firstUser === false) {

105

console.log("No users found");

106

} else {

107

console.log("First user:", firstUser.name);

108

}

109

110

// Get counts

111

const totalUsers = db().count();

112

const activeCount = db({ active: true }).count();

113

const inactiveCount = db({ active: false }).count();

114

115

// Export as JSON

116

const jsonData = db({ department: "Engineering" }).stringify();

117

localStorage.setItem('engineeringData', jsonData);

118

119

// Conditional operations

120

if (db({ role: "admin" }).count() === 0) {

121

console.log("No administrators found!");

122

}

123

```

124

125

### Data Selection and Projection

126

127

Extract specific fields or compute derived values from query results.

128

129

```javascript { .api }

130

/**

131

* Select specific columns/properties from results

132

* @param columns - Column names to extract

133

* @returns Array of values or arrays of values

134

*/

135

select(...columns: string[]): any[] | any[][];

136

137

/**

138

* Get unique values from one or more columns

139

* @param columns - Column names to extract unique values from

140

* @returns Array of unique values (single column) or array of unique value arrays (multiple columns)

141

*/

142

distinct(...columns: string[]): any[] | any[][];

143

```

144

145

**Usage Examples:**

146

147

```javascript

148

// Select single column

149

const names = db({ active: true }).select("name");

150

// Returns: ["Alice", "Bob", "Charlie"]

151

152

// Select multiple columns

153

const userInfo = db({ department: "Sales" }).select("name", "email", "salary");

154

// Returns: [["Alice", "alice@company.com", 75000], ["Bob", "bob@company.com", 68000]]

155

156

// Get unique values from single column

157

const departments = db().distinct("department");

158

// Returns: ["Engineering", "Sales", "Marketing", "HR"]

159

160

const locations = db({ active: true }).distinct("location");

161

// Returns: ["New York", "San Francisco", "Austin"]

162

163

// Get unique combinations from multiple columns

164

const roleDeptCombos = db().distinct("role", "department");

165

// Returns: [["Manager", "Sales"], ["Developer", "Engineering"], ["Manager", "Engineering"]]

166

167

// Combine with filtering

168

const seniorRoles = db({ experience: { gte: 5 } }).distinct("role");

169

const highEarners = db({ salary: { gte: 100000 } }).select("name", "salary", "department");

170

```

171

172

### Data Aggregation

173

174

Perform mathematical operations and statistical calculations on numeric data.

175

176

```javascript { .api }

177

/**

178

* Calculate sum of numeric columns (all columns are summed together)

179

* @param columns - Column names to sum

180

* @returns Single sum value combining all specified columns

181

*/

182

sum(...columns: string[]): number;

183

184

/**

185

* Find minimum value in a column

186

* @param column - Column name to analyze

187

* @returns Minimum value found

188

*/

189

min(column: string): any;

190

191

/**

192

* Find maximum value in a column

193

* @param column - Column name to analyze

194

* @returns Maximum value found

195

*/

196

max(column: string): any;

197

```

198

199

**Usage Examples:**

200

201

```javascript

202

// Calculate sums (single column)

203

const totalSalary = db({ department: "Engineering" }).sum("salary");

204

205

// Calculate combined sum (all columns summed together)

206

const totalCompensation = db({ active: true }).sum("salary", "bonus", "commission");

207

// Returns: single number (salary + bonus + commission for all active users)

208

209

// Find min/max values

210

const youngestAge = db({ active: true }).min("age");

211

const oldestAge = db({ active: true }).max("age");

212

const lowestSalary = db({ department: "Sales" }).min("salary");

213

const highestSalary = db({ department: "Sales" }).max("salary");

214

215

// Aggregate analysis

216

const salesStats = {

217

count: db({ department: "Sales" }).count(),

218

totalSalary: db({ department: "Sales" }).sum("salary"),

219

avgSalary: db({ department: "Sales" }).sum("salary") / db({ department: "Sales" }).count(),

220

minSalary: db({ department: "Sales" }).min("salary"),

221

maxSalary: db({ department: "Sales" }).max("salary")

222

};

223

224

// Multiple aggregations

225

const departmentSums = db().distinct("department").map(dept => ({

226

department: dept,

227

totalSalary: db({ department: dept }).sum("salary"),

228

employeeCount: db({ department: dept }).count()

229

}));

230

```

231

232

### Iteration and Transformation

233

234

Process records individually or transform entire result sets.

235

236

```javascript { .api }

237

/**

238

* Iterate over each record in the result set

239

* @param callback - Function to call for each record

240

* @returns QueryResult for chaining

241

*/

242

each(callback: (record: object, index?: number) => any): QueryResult;

243

244

/**

245

* Transform each record and return new array

246

* @param callback - Function to transform each record

247

* @returns Array of transformed values

248

*/

249

map(callback: (record: object, index?: number) => any): any[];

250

251

/**

252

* Inject record values into string templates

253

* @param template - String template with {property} placeholders

254

* @param returnArray - Whether to return array of strings (default: false)

255

* @returns Single string or array of strings

256

*/

257

supplant(template: string, returnArray?: boolean): string | string[];

258

```

259

260

**Usage Examples:**

261

262

```javascript

263

// Iterate with each

264

db({ active: true }).each(function(user, index) {

265

console.log(`${index + 1}. ${user.name} - ${user.email}`);

266

267

// Return TAFFY.EXIT to break early

268

if (index >= 5) return TAFFY.EXIT;

269

});

270

271

// Transform with map

272

const emailList = db({ active: true }).map(function(user) {

273

return user.email.toLowerCase();

274

});

275

276

const userSummaries = db({ department: "Engineering" }).map(function(user, index) {

277

return {

278

id: user.id,

279

fullName: `${user.firstName} ${user.lastName}`,

280

seniority: user.experience >= 5 ? "Senior" : "Junior",

281

position: index + 1

282

};

283

});

284

285

// Template substitution

286

const emailTemplate = "Hello {name}, your account balance is ${balance}.";

287

288

// Single string (concatenated)

289

const emailBody = db({ id: 123 }).supplant(emailTemplate);

290

// Returns: "Hello John Smith, your account balance is $1250.50."

291

292

// Array of strings (one per record)

293

const emailBodies = db({ active: true }).supplant(emailTemplate, true);

294

// Returns: ["Hello Alice...", "Hello Bob...", "Hello Charlie..."]

295

296

// HTML generation

297

const tableRows = db({ department: "Sales" }).supplant(

298

"<tr><td>{name}</td><td>{email}</td><td>${salary}</td></tr>",

299

true

300

);

301

```

302

303

### Asynchronous Operations

304

305

Execute callbacks with optional delays for non-blocking operations.

306

307

```javascript { .api }

308

/**

309

* Execute callback with query results after optional delay

310

* @param fn - Callback function to execute

311

* @param delay - Delay in milliseconds (default: 0)

312

* @returns QueryResult for chaining

313

*/

314

callback(fn: (results: object[]) => void, delay?: number): QueryResult;

315

```

316

317

**Usage Examples:**

318

319

```javascript

320

// Immediate callback

321

db({ active: true }).callback(function(results) {

322

console.log('Found', results.length, 'active users');

323

results.forEach(user => {

324

console.log('- ' + user.name);

325

});

326

});

327

328

// Delayed callback

329

db({ needsNotification: true }).callback(function(results) {

330

results.forEach(user => {

331

sendNotificationEmail(user.email, user.message);

332

});

333

}, 1000); // Wait 1 second before executing

334

335

// Chain with other operations

336

db({ status: "pending" })

337

.update({ status: "processing" })

338

.callback(function(results) {

339

console.log('Started processing', results.length, 'items');

340

})

341

.filter({ priority: "high" })

342

.callback(function(results) {

343

console.log('High priority items:', results.length);

344

}, 500);

345

```

346

347

### Table Joins

348

349

Perform SQL-like inner joins between TaffyDB instances or query results with flexible condition matching.

350

351

```javascript { .api }

352

/**

353

* Join current query results with another table using specified conditions

354

* @param table - TaffyDB instance or QueryResult to join with

355

* @param conditions - Join conditions (arrays, functions, or mixed)

356

* @returns QueryResult containing joined records

357

*/

358

join(table: TaffyDatabase | QueryResult, ...conditions: (JoinCondition | JoinFunction)[]): QueryResult;

359

360

// Join condition types

361

type JoinCondition = [string, string] | [string, string, string]; // [leftField, rightField] or [leftField, operator, rightField]

362

type JoinFunction = (leftRow: object, rightRow: object) => boolean;

363

```

364

365

**Usage Examples:**

366

367

```javascript

368

// Basic join on matching fields

369

const users = TAFFY([

370

{ id: 1, name: "Alice", deptId: 10 },

371

{ id: 2, name: "Bob", deptId: 20 },

372

{ id: 3, name: "Charlie", deptId: 10 }

373

]);

374

375

const departments = TAFFY([

376

{ id: 10, name: "Engineering", budget: 500000 },

377

{ id: 20, name: "Sales", budget: 300000 }

378

]);

379

380

// Join users with departments on matching IDs

381

const userDeptInfo = users().join(departments, ["deptId", "id"]);

382

// Results contain combined records with department info merged

383

384

// Join with custom comparison operator

385

const highBudgetUsers = users().join(departments, ["deptId", "===", "id"]);

386

387

// Join with custom function condition

388

const customJoin = users({ name: { like: "A" } }).join(departments, function(user, dept) {

389

return user.deptId === dept.id && dept.budget > 400000;

390

});

391

392

// Multiple join conditions (all must be true)

393

const complexJoin = users().join(departments,

394

["deptId", "id"], // Basic field matching

395

function(user, dept) { // Custom condition

396

return user.name.length > 3;

397

}

398

);

399

400

// Available operators in array conditions

401

const operatorExamples = users().join(departments,

402

["deptId", "===", "id"], // Strict equality (default)

403

["deptId", "!==", "id"], // Not equal

404

["deptId", "<", "id"], // Less than

405

["deptId", ">", "id"], // Greater than

406

["deptId", "<=", "id"], // Less than or equal

407

["deptId", ">=", "id"], // Greater than or equal

408

["deptId", "==", "id"], // Loose equality

409

["deptId", "!=", "id"] // Loose inequality

410

);

411

```

412

413

**Join Result Structure:**

414

415

```javascript

416

// When joining, conflicting field names are prefixed with "right_"

417

const result = users().join(departments, ["deptId", "id"]).get();

418

// Example result record:

419

// {

420

// id: 1, // From left table (users)

421

// name: "Alice", // From left table (users)

422

// deptId: 10, // From left table (users)

423

// right_id: 10, // From right table (departments) - prefixed to avoid conflict

424

// right_name: "Engineering", // From right table (departments) - prefixed

425

// budget: 500000 // From right table (departments) - no conflict, no prefix

426

// }

427

428

// Chain joins with other operations

429

const filteredJoin = users({ name: { left: "A" } })

430

.join(departments, ["deptId", "id"])

431

.filter({ budget: { gt: 400000 } })

432

.order("name")

433

.get();

434

```

435

436

### Advanced Result Processing

437

438

Complex data manipulation combining multiple query operations.

439

440

**Usage Examples:**

441

442

```javascript

443

// Batch processing with pagination

444

function processAllUsers(pageSize = 100) {

445

const totalUsers = db({ active: true }).count();

446

const totalPages = Math.ceil(totalUsers / pageSize);

447

448

for (let page = 1; page <= totalPages; page++) {

449

const users = db({ active: true })

450

.order("id")

451

.start((page - 1) * pageSize + 1)

452

.limit(pageSize)

453

.get();

454

455

// Process batch

456

users.forEach(user => {

457

processUser(user);

458

});

459

}

460

}

461

462

// Conditional updates based on aggregations

463

const avgSalary = db({ department: "Engineering" }).sum("salary") /

464

db({ department: "Engineering" }).count();

465

466

db({ department: "Engineering" })

467

.filter(function() { return this.salary < avgSalary * 0.8; })

468

.update({ needsReview: true, reviewDate: new Date() });

469

470

// Complex reporting

471

const departmentReport = db().distinct("department").map(dept => {

472

const deptEmployees = db({ department: dept });

473

return {

474

department: dept,

475

totalEmployees: deptEmployees.count(),

476

activeEmployees: deptEmployees.filter({ active: true }).count(),

477

totalSalary: deptEmployees.sum("salary"),

478

avgSalary: deptEmployees.sum("salary") / deptEmployees.count(),

479

topPerformer: deptEmployees.order("performance desc").first()

480

};

481

});

482

```