├── .gitignore ├── License ├── README.md ├── docs ├── CNAME ├── _config.yml ├── beginner.html ├── extentions.html ├── index.html ├── index_files │ ├── XRegExp.js.download │ ├── bootstrap-alert.js.download │ ├── bootstrap-button.js.download │ ├── bootstrap-carousel.js.download │ ├── bootstrap-collapse.js.download │ ├── bootstrap-dropdown.js.download │ ├── bootstrap-modal.js.download │ ├── bootstrap-popover.js.download │ ├── bootstrap-responsive.css │ ├── bootstrap-scrollspy.js.download │ ├── bootstrap-tab.js.download │ ├── bootstrap-tooltip.js.download │ ├── bootstrap-transition.js.download │ ├── bootstrap-typeahead.js.download │ ├── bootstrap.css │ ├── ga.js.download │ ├── jquery.js.download │ ├── saved_resource(1).html │ ├── saved_resource.html │ ├── shBrushJScript.js.download │ ├── shCore.js.download │ ├── taffydbboxV3.jpg │ ├── timeline.619317855a58aa2366562a395f9e40ef.js.download │ └── widgets.js.download ├── working_with_data.html └── writing_queries.html ├── package.json ├── taffy-min.js ├── taffy.js └── test └── t.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | *.swp 4 | npm-debug.log 5 | node_modules 6 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Copyright 2018 joe@taffydb.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TaffyDB (taffy.js) 2 | 3 | TaffyDB is an open source JavaScript library that provides powerful 4 | in-memory database capabilities to both browser and server applications. 5 | 6 | ## Introduction 7 | 8 | Have you ever noticed how JavaScript object literals look a lot like 9 | records? And that if you wrap a group of them up in an array you have 10 | something that looks a lot like a database table? We did too. 11 | We created TaffyDB easily and efficiently manipulate these 'tables' 12 | with a uniform and familiar SQL-like interface. 13 | 14 | We use TaffyDB instead of ad-hoc data manipulation routines throughout 15 | our applications. This reduces development time, improves performance, 16 | simplifies maintenance, *and* increases quality. 17 | 18 | Please see the [official website](http://www.taffydb.com) for more 19 | complete documentation. 20 | 21 | ## What makes it sticky 22 | 23 | - Extremely fast 24 | - Powerful JavaScript-centric data selection engine 25 | - SQL inspired features such as insert, update, unique, count, and more 26 | - Robust cross browser support 27 | - Easily extended with your own functions 28 | - Compatible with any DOM library (jQuery, YUI, Dojo, etc) 29 | 30 | TaffyDB is compatible with all modern browsers: IE9+, FF3+, Safari 5+, 31 | and Chrome 1.0+. It also works in NodeJS 0.10+. 32 | 33 | ## Create a DB 34 | Just pass in a JSON array: 35 | 36 | ```js 37 | var product_db = TAFFY([ 38 | { "item" : 1, 39 | "name" : "Blue Ray Player", 40 | "price" : 99.99 41 | }, 42 | { "item" : 2, 43 | "name" : "3D TV", 44 | "price" : 1799.99 45 | } 46 | ]); 47 | ``` 48 | 49 | ## Example queries 50 | 51 | ```js 52 | // where item is equal to 1 53 | var item1 = products({item:1}); 54 | 55 | // where price is less than 100 56 | var lowPricedItems = products({price:{lt:100}}); 57 | 58 | // where name is like "Blue Ray" 59 | var blueRayPlayers = products({name:{like:"Blue Ray"}}); 60 | 61 | // get first record 62 | products().first(); 63 | 64 | // get last record 65 | products().last(); 66 | ``` 67 | 68 | ## Example record manipulation 69 | 70 | ```js 71 | // update the price of the Blue Ray Player to 89.99 72 | products({item:1}).update({price:89.99}); 73 | 74 | // loop over the records and call a function 75 | products().each(function (r) {alert(r.name)}); 76 | 77 | // sort the records by price descending 78 | products.sort("price desc"); 79 | 80 | // select only the item names into an array 81 | products().select("name"); // returns ["3D TV","Blue Ray Player"] 82 | 83 | // Inject values from a record into a string template. 84 | // Row value will be set to "
TaffyDB is very easy to get started with. This brief turtoial will introduce you to a few of the core concepts and should be enough to get started even if you aren't already a web developer.
146 | 147 |It is recmmended that you download and use your own copy of TaffyDB, but for the purposes of playing around you can use the latest version right off of GitHub. If you have never created a web page before you can simply create a text document, include the code below, and save it to your desktop as test.html.
149 |<html> 150 | <head> 151 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 152 | </head> 153 | <body> 154 | </body> 155 | 156 | </html>157 |
The script tag imports TaffyDB right onto the page.
158 | 159 |Let's create a DB to store some city information. You'll need another script tag and you'll be writing JavaScript.
161 |<html> 162 | <head> 163 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 164 | <script> 165 | 166 | var cities = TAFFY(); 167 | 168 | </script> 169 | </head> 170 | <body> 171 | </body> 172 | 173 | </html>174 |
You can add records on creation and via the .insert() method. Below we are doing both.
176 |<html> 177 | <head> 178 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 179 | <script> 180 | 181 | var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]); 182 | 183 | cities.insert({name:"Portland",state:"OR"}); 184 | 185 | </script> 186 | </head> 187 | <body> 188 | </body> 189 | 190 | </html>191 |
Our city db is itself a function that accepts a filter object (an object that will be matched to records). Let's query for Boston. We will alert the .count() method to see our results.
193 |<html> 194 | <head> 195 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 196 | <script> 197 | 198 | var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]); 199 | 200 | cities.insert({name:"Portland",state:"OR"}); 201 | 202 | alert(cities({name:"Boston"}).count()); 203 | 204 | </script> 205 | </head> 206 | <body> 207 | </body> 208 | 209 | </html>210 | 211 |
You can chain together. Below we will get the first two records from the DB and use the .each() method to alert their names.
213 |<html> 214 | <head> 215 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 216 | <script> 217 | 218 | var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]); 219 | 220 | cities.insert({name:"Portland",state:"OR"}); 221 | 222 | cities().limit(2).each(function (r) {alert(r.name)}); 223 | 224 | </script> 225 | </head> 226 | <body> 227 | </body> 228 | 229 | </html>230 | 231 |
You may have noticed that New York is in the wrong state. Let's fix that and alert the new state.
233 |<html> 234 | <head> 235 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 236 | <script> 237 | 238 | var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]); 239 | 240 | cities.insert({name:"Portland",state:"OR"}); 241 | 242 | cities({name:"New York"}).update({state:"NY"}); 243 | 244 | alert(cities({name:"New York"}).first().state); 245 | 246 | 247 | </script> 248 | </head> 249 | <body> 250 | </body> 251 | 252 | </html>253 | 254 |
Sorting is a big part of TaffyDB using the .order() method.
256 |<html> 257 | <head> 258 | <script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script> 259 | <script> 260 | 261 | var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]); 262 | 263 | cities.insert({name:"Portland",state:"OR"}); 264 | 265 | alert(cities().order("name").first().name); 266 | 267 | </script> 268 | </head> 269 | <body> 270 | </body> 271 | 272 | </html>273 |
There are a lot of other methods you can use against your data. Some highlights include .remove() to delete records, .get() to get an array of records, and .supplant to merge records with a string template. Continue to browse the docs for more ways to use TaffyDB.
275 | 276 | 277 | 278 | 279 |TaffyDB is easy to extend. Simply use the extend method to add a new method to all TaffyDB collections on your page.
146 |Here is an example that creates an "avg" method that takes a column and returns the avg value.
147 |// Create a new empty database 148 | TAFFY.extend("avg",function (c) { 149 | // This runs the query or returns the results if it has already run 150 | this.context({ 151 | results: this.getDBI().query(this.context()) 152 | }); 153 | // setup the sum 154 | var total = 0; 155 | // loop over every record in the results and sum up the column. 156 | TAFFY.each(this.context().results,function (r) { 157 | total = total + r[c]; 158 | }) 159 | 160 | // divide the total by the number of records and return 161 | return total/this.context().results.length; 162 | }); 163 |164 |
What can you build?
165 | 166 | 167 |An opensouce library that brings database features into your JavaScript applications.
146 |How you ever noticed how JavaScript object literals look a lot like records? And that if you wrap a group of them up in an array you have something that looks a lot like a database table? TaffyDB is a library to bring powerful database funtionality to that concept and rapidly improve the way you work with data inside of JavaScript.
149 | 150 |// Create DB and fill it with records 163 | var friends = TAFFY([ 164 | {"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"}, 165 | {"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"}, 166 | {"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"}, 167 | {"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"} 168 | ]); 169 |170 | 171 |
// Find all the friends in Seattle 173 | friends({city:"Seattle, WA"}); 174 | 175 | // Find John Smith, by ID 176 | friends({id:1}); 177 | 178 | // Find John Smith, by Name 179 | friends({first:"John",last:"Smith"}); 180 |181 | 182 |
// Kelly's record 184 | var kelly = friends({id:2}).first(); 185 | 186 | // Kelly's last name 187 | var kellyslastname = kelly.last; 188 | 189 | // Get an array of record ids 190 | var cities = friends().select("id"); 191 | 192 | // Get an array of distinct cities 193 | var cities = friends().distinct("city"); 194 | 195 | // Apply a function to all the male friends 196 | friends({gender:"M"}).each(function (r) { 197 | alert(r.name + "!"); 198 | }); 199 |200 | 201 |
// Move John Smith to Las Vegas 203 | friends({first:"John",last:"Smith"}).update({city:"Las Vegas, NV:"}); 204 | 205 | // Remove Jennifer Gill as a friend 206 | friends({id:4}).remove(); 207 | 208 | // insert a new friend 209 | friends.insert({"id":5,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"}); 210 |211 | 212 | 213 | 214 | 215 | 216 |
/js/SyntaxHighlighter/scripts/XRegExp.js
was not found on this server./js/bootstrap-alert.js
was not found on this server./js/bootstrap-button.js
was not found on this server./js/bootstrap-carousel.js
was not found on this server./js/bootstrap-collapse.js
was not found on this server./js/bootstrap-dropdown.js
was not found on this server./js/bootstrap-modal.js
was not found on this server./js/bootstrap-popover.js
was not found on this server./js/bootstrap-scrollspy.js
was not found on this server./js/bootstrap-tab.js
was not found on this server./js/bootstrap-tooltip.js
was not found on this server./js/bootstrap-transition.js
was not found on this server./js/bootstrap-typeahead.js
was not found on this server./js/jquery.js
was not found on this server./js/SyntaxHighlighter/scripts/shBrushJScript.js
was not found on this server./js/SyntaxHighlighter/scripts/shCore.js
was not found on this server.You use the global TAFFY function to create a new database.
148 |// Create a new empty database 149 | var db = TAFFY(); 150 | 151 | // Create a new database a single object (first record) 152 | var db = TAFFY({record:1,text:"example"}) 153 | 154 | // Create a new database using an array 155 | var db = TAFFY([{record:1,text:"example"}]) 156 | 157 | // Create a new database using a JSON string 158 | var db = TAFFY('[{"record":1,"text":"example"}]') 159 |160 |
Once you have a database you'll be able to call your variable as function. This will setup a query and return a collection of methods to work with the results of that query.
162 |165 | db() 166 | | 167 |
168 | Takes: One or more Strings, Records, A Filter Objects, Arrays, or Functions. 169 | |
170 |
171 | Returns: A Query Object 172 | |
173 | 174 | Used to query the database and return a method collection to start working with the data. 175 | | 176 |
179 | db(); // returns all rows 180 |181 | |
182 |
In addition to the query function you have a couple of top level methods to use.
186 |189 | db.insert() 190 | | 191 |
192 | Takes: An object or array of objects/json strings to insert. 193 | 194 | 195 | Optional: Call Event override 196 | true runs onInsert event (default) 197 | false does not onInsert event 198 | |
199 |
200 | Returns: A query pointing to the inserted records 201 | |
202 | 203 | Inserts records into the database. 204 | | 205 |
208 | db.merge() 209 | | 210 |
211 | Takes: An object or array of objects/json strings to insert. 212 | 213 | 214 | Optional: Key 215 | identity column to be used to match records against the existing db. Default "id". 216 | true runs onInsert for new records and onUpdate for changed records 217 | 218 | 219 | Optional: Call Event override 220 | false does not run insert or update event (default) 221 | true runs onInsert for new records and onUpdate for changed records 222 | |
223 |
224 | Returns: A query pointing to the changed or inserted records 225 | |
226 | 227 | Inserts or replaces records in an existing db. 228 | | 229 |
232 | db.insert({column:"value"}); // inserts one record 233 | 234 | db.insert({column:"value"},false); // insert but do not call onInsert event235 | |
236 | |||
239 | db.order() 240 | | 241 |
242 | Takes: A string listing columns to order by separated by commas. 243 | Optional: Use asec, desc, logical, and logicaldesc to influencence sort direction. 244 | |
245 |
246 | Returns: true 247 | |
248 |
249 | Sorts the db by column. Note that logical sorting is default. 250 | Note: db.sort() is different than db().order() in that sort() changes the order of the records in the database while order() only impacts the order of results returned from a query. 251 | |
252 |
255 | db.order("columnname"); // orders collection by columnname256 | |
257 | |||
260 | db.store() 261 | | 262 |
263 | Takes: A string with the storage name for the DB 264 | |
265 |
266 | Returns: true if data was returned from localStorage, false if no data returned 267 | |
268 |
269 | Sets up a localStorage collection for a given name. If data exists already the data will be loaded into the collection. Changes are auto synced to localStorage. 270 | Pass in false to terminate storing the collection (data in localstorage will be unchanged). 271 | 272 | Note: localStorage is not avaliable in all browsers. If localStorage is not found then .store() will be ignored. 273 | 274 | |
275 |
278 | db.store("name"); // starts storing records in local storage279 | |
280 | |||
283 | db.settings() 284 | | 285 |
286 | Takes: An object. 287 | |
288 |
289 | Returns: The settings object 290 | |
291 |
292 | Used to modify the following settings on each DB:
293 |
|
305 |
308 | db.settings({template:{show:true}}); // sets the template to have a show value set to true by default on all records 309 | 310 | db.settings({onUpdate:function () {alert(this)}}); // sets the onUpdate event 311 | 312 |313 | |
314 |
Any call to data collections root function will return a new query object. The methods below can be used 320 | to interact with the data.
321 |324 | db().update() 325 | | 326 |
327 | Takes: Any: 328 | An object to be merged with the matching objects. 329 | A function that will return the modified record for update. 330 | Two arguments: a string column name and a value to set the column to 331 | 332 | 333 | Optional Call Event override 334 | true runs onUpdate event (default) 335 | false does not onUpdate event 336 | |
337 |
338 | Returns: Query Object 339 | |
340 | 341 | Updates the records in the query set. 342 | | 343 |
346 | db().update({column:"value"}); // sets column to "value" for all matching records 347 | 348 | db().update("column","value"); // sets column to "value" for all matching records 349 | 350 | db().update(function () {this.column = "value";return this;}); // sets column to "value" for all matching records 351 | 352 | 353 | db().update({column:"value"},false); // update but do not call onUpdate event354 | |
355 | |||
358 | db().remove() 359 | | 360 |
361 | Takes: 362 | 363 | Optional Call Event override 364 | true runs onUpdate event (default) 365 | false does not onUpdate event 366 | |
367 |
368 | Returns: Count of removed records. 369 | |
370 | 371 | Removes records from the database 372 | | 373 |
376 | db().remove(); // removes all matching records from the database 377 | 378 | db().remove(true); // removes but do not call onRemove event379 | |
380 | |||
383 | db().filter() 384 | | 385 |
386 | Takes: One or more Strings, Records, A Filter Objects, Arrays, or Functions. 387 | 388 | |
389 |
390 | Returns: Query Object 391 | |
392 |
393 | See Filtering 394 | Applies a sub filter and returns a new Query Object to let you access the results of the filter. 395 | |
396 |
399 | db().filter({column:value}); 400 | 401 | db().filter({column:value}).count(); 402 | 403 | collection({column:{gte:value}}).filter({column:{lte:value}}).count(); 404 |405 | |
406 | |||
409 | db().order() 410 | | 411 |
412 | Takes: A string listing columns to order by separated by commas. 413 | Optional: Use asec, desc, logical, and logicaldesc to influence sort direction. 414 | |
415 |
416 | Returns: Query Object 417 | |
418 | 419 | Sorts the query results by column based. Note that logical sorting is default. 420 | Note: db.sort() is different than db().order() in that sort() changes the order of the records in the database while order() only impacts the order of results returned from a query. 421 | 422 | | 423 |
426 | db().order("col1"); // sorts by col1 using a logical sort 427 | 428 | db().order("col1 asec, col2 asec"); // sorts by col1 then col2 429 | 430 | db().order("col1 desc"); // sorts by col1 descending 431 | 432 | db().order("col1 logicaldesc"); // sorts by col1 using a logical sort descending 433 |434 | |
435 | |||
438 | db().limit() 439 | | 440 |
441 | Takes: A number. 442 | |
443 |
444 | Returns: Query Object 445 | |
446 | 447 | Limits the number of results in a query set. 448 | | 449 |
452 | db().limit(15); // Limits returned results to first 15453 | |
454 | |||
457 | db().start() 458 | | 459 |
460 | Takes: A number. 461 | |
462 |
463 | Returns: Query Object 464 | |
465 | 466 | Sets the starting record number. Used for offset and paging. 467 | | 468 |
471 | db().start(15); // Starts returning results at record 15472 | |
473 | |||
476 | db().each() 477 | | 478 |
479 | Takes: A function. 480 | |
481 |
482 | Returns: Query Object 483 | |
484 | 485 | Runs one or more functions once for every record in the query. 486 | | 487 |
490 | db().each(function (record,recordnumber) { 491 | alert(record["balance"]); 492 | }); // alerts the value of the balance column for each record493 | |
494 | |||
497 | db().map() 498 | | 499 |
500 | Takes: A function. 501 | |
502 |
503 | Returns: An array of results from your function being run against the records in the query. 504 | |
505 | 506 | Runs your function against each record in the query and returns the results as an array. 507 | | 508 |
511 | db().map(function (record,recordnumber) { 512 | return record.balance*0.2; 513 | }); // returns an array of numbers that are each 20% of the actual balance for each record514 | |
515 | |||
518 | db().callback() 519 | | 520 |
521 | Takes: A function and an (optional) delay. 522 | |
523 | 524 | 525 | | 526 |527 | Used for lazy query execution and to prevent blocking. Provided function will be called with current Quote Object after query has run in a setTimeout block. 528 | | 529 |
532 | db().callback(function () { 533 | alert(this.count()); // alert count of matching records 534 | });535 | |
536 | |||
539 | db().get() 540 | | 541 |542 | 543 | | 544 |
545 | Returns: An array of all matching records. 546 | |
547 | 548 | Prefered method for extracting data. Returns an array of matching records. Also used for exporting records form the database. 549 | | 550 |
553 | db().get(); // returns an array of all matching records554 | |
555 | |||
558 | db().stringify() 559 | | 560 |561 | 562 | | 563 |
564 | Returns: A JSON representation of an array of all matching records. 565 | |
566 | 567 | Used for exporting data as JSON text. Returns a JSON array filled with JSON objects for each record. 568 | | 569 |
572 | db().stringify(); // returns a JSON array of all matching records573 | |
574 | |||
577 | db().first() 578 | | 579 |580 | 581 | | 582 |
583 | Returns: A single record. 584 | |
585 | 586 | Returns the first record in a record set. 587 | | 588 |
591 | db().first(); // returns the first record out of all matching records.592 | |
593 | |||
596 | db().last() 597 | | 598 |599 | 600 | | 601 |
602 | Returns: A single record. 603 | |
604 | 605 | Returns the last record in a record set. 606 | | 607 |
610 | db().last(); // returns the last record out of all matching records.611 | |
612 | |||
615 | db().sum() 616 | | 617 |
618 | Takes: One or more column names. 619 | |
620 |
621 | Returns: A number. 622 | |
623 | 624 | Returns the sum total of the column or columns passed into it. 625 | | 626 |
629 | db().last("balance"); // returns the sum of the "balance" column.630 | |
631 | |||
634 | db().min() 635 | | 636 |
637 | Takes: Column name. 638 | |
639 |
640 | Returns: A number or value. 641 | |
642 | 643 | Returns the min value for the column passed in. 644 | | 645 |
648 | db().min("balance"); // returns the lowest value of the "balance" column.649 | |
650 | |||
653 | db().max() 654 | | 655 |
656 | Takes: Column name. 657 | |
658 |
659 | Returns: A number or value. 660 | |
661 | 662 | Returns the max value for the column passed in. 663 | | 664 |
667 | db().max("balance"); 668 | // returns the highest value of the "balance" column.669 | |
670 | |||
673 | db().select() 674 | | 675 |
676 | Takes: One or more column names. 677 | |
678 |
679 | Returns: For one column: An array of values. 680 | For two or more columns: An array of arrays of values. 681 | |
682 | 683 | Used to select columns out the database. Pass in column names to get back an array of values. 684 | | 685 |
688 | db().select("charges","credits","balance"); 689 | // returns an array of arrays in this format [[-24,20,-4]] 690 | 691 | db().select("balance"); 692 | // returns an array of values in this format [-4,6,7,10] 693 |694 | 695 | |
696 | |||
699 | db().distinct() 700 | | 701 |
702 | Takes: One or more column names. 703 | |
704 |
705 | Returns: For one column: An array of values. 706 | For two or more columns: An array of arrays of values. 707 | |
708 | 709 | Used to select distinct values from the database for one or more columns. Pass in column names to get back an array of distinct values. 710 | | 711 |
714 | db().distinct("title","gender"); 715 | // returns an array of arrays in this format [["Mr.","Male"],["Ms.","Female"]] 716 | 717 | db().distinct("title"); 718 | // returns an array of values in this format ["Mr.","Ms.","Mrs."]719 | 720 | |
721 | |||
724 | db().supplant() 725 | | 726 |
727 | Takes: A string template. 728 | Optional return array flag. 729 | |
730 |
731 | Returns: Defaults to a string. If return array flag is true then an array of strings with an entry for each record. 732 | |
733 | 734 | Used to merge records with a template formated with {key} values to be replaced with real values from the records. 735 | | 736 |
739 | db().supplant("<tr><td>{balance}</td></tr>"); 740 | // returns a string in this format "<tr><td>-4</td></tr><tr><td>6</td></tr>" 741 | 742 | db().supplant("<tr><td>{balance}</td></tr>",true); 743 | // returns an array of strings format ["<tr><td>-4</td></tr>","<tr><td>6</td></tr>"] 744 |745 | 746 | |
747 | |||
750 | db().join() 751 | | 752 |
753 | Takes: 1. A second db or reference to a db query. 754 | 2. One or more functions to be used as join conditions or 755 | An an array of one or more join conditions 756 | 757 | |
758 |
759 | Returns: A db query object containing the joined rows. 760 | |
761 |
762 | Used to join two dbs and/or queries together and produce a hybrid query containing the joined data. 763 | [EXPERIMENTAL FEATURE] 764 | |
765 |
768 |
769 | // City DB 770 | city_db = TAFFY([ 771 | {name:'New York',state:'NY'}, 772 | {name:'Las Vegas',state:'NV'}, 773 | {name:'Boston',state:'MA'} 774 | ]); 775 | 776 | // State DB 777 | state_db = TAFFY([ 778 | {name: 'New York', abbreviation: 'NY'}, 779 | {name: 'Nevada', abbreviation: 'NV'}, 780 | {name: 'Massachusetts', abbreviation: 'MA'} 781 | ]); 782 | 783 | // Conditional Join 784 | city_db() 785 | .join( state_db, [ 'state', 'abbreviation' ]); 786 | 787 | // Conditional Join with optional === 788 | city_db() 789 | .join( state_db, [ 'state', '===', 'abbreviation' ]); 790 | 791 | // Conditional Join using function 792 | city_db() 793 | .join( state_db, function (l, r) { 794 | return (l.state === r.abbreviation); 795 | }); 796 |797 | 798 | |
799 |
The heart of TaffyDB and any database is running queries against your data. This is done after creation of your database by calling the root function and building Filter Objects.
146 |// Create a new empty database 147 | var db = TAFFY(); 148 | 149 | // Run a query against the DB to return all rows 150 | db(); 151 | 152 | // Real world example - remove all records 153 | db().remove(); 154 |155 | 156 |
Every object within a TaffyDB collection has a ___id value set by TaffyDB. This value is not intended for you to know, but is useful when building dynamic applications. This can be used to lookup a record by passing it into the root function as a string.
158 |// Looks up a record based on its id 159 | db("T000008R000002"); 160 | 161 | // Real world example - update records "status" column 162 | db("T000008R000002").update({status:"Active"}); 163 |164 |
This also works if you have a copy of the whole record.
165 |// get the first record 166 | var firstRecord = db().first(); 167 | 168 | // look up this record again 169 | db(firstRecord); 170 | 171 | // Real world example - update records "status" column 172 | db(firstRecord).update({status:"Active"}); 173 |174 |
To give you full control over the results of your query you can always pass in a function. Just have it return true if you want the record in your final results.
176 |// functional example, returns all records 177 | db(function () { 178 | return true; 179 | }); 180 | 181 | 182 | // Real world example - function returns records with a status of active 183 | db(function () { 184 | return (this.status == "Active") ? true : false; 185 | }); 186 |187 | 188 | 189 |
TaffyDB uses a very JavaScript centric Filter Object for looking up queries. There is no string concatenation and you can quickly compose these by hand or dynamically from within your app. The filter object is compared against each record using some business rules and if it passes the record remains in the results set.
191 | 192 |The most common Filter Object is used simply to check if a column is equal to value.
193 |// does a match for column and value 194 | db({column:"value"}); 195 | 196 | 197 | // Real world example - records with a status of active 198 | db({status:"Active"}); 199 |200 |
This is the short form of this
201 |// does a match for column and value 202 | db({column:{is:"value"}}); 203 | 204 | 205 | // Real world example - records with a status of active 206 | db({status:{is:"Active"}}); 207 |208 |
The "is" part of this expressions can be swapped out for a variety of other comparisons as listed below.
209 |For any comparison operator you can quote it and add a ! sign to reverse the meaning.
211 |// does a match for column that is not a value 212 | db({column:{"!is":"value"}}); 213 | 214 | // Real world example - records with a status other than of active 215 | db({status:{"!is":"Active"}}); 216 |217 |
Using the almighty comma you can add additional lookups to you Filter Object.
219 |// does a match for column that is a value and column2 is a value 220 | db({column:"value",column2:"value"}); 221 | 222 | // Real world example - records with a status of active and a role of admin 223 | db({status:"Active",role:"Admin"}); 224 |225 |
You can also pass in additional Filter Objects into the function
226 |// does a match for column that is a value and column2 is a value 227 | db({column:"value"},{column2:"value"}); 228 | 229 | // Real world example - records with a status of active and a role of admin 230 | db({status:"Active"},{role:"Admin"}); 231 |232 |
In a database you can use "in" to pass in a collection of values to compare against. This is possible in TaffyDB via the array.
234 |// does a match for column that is one of two values 235 | db({column:["value","value2"]); 236 | 237 | // Real world example - records with a status of active or pending 238 | db({status:["Active","Pending"]}); 239 |240 |
You can also pass in an array of Filter Objects with each one being treated as a logical OR.
241 |// does a match for column that is one of two values 242 | db([{column:"value"},{column:"value2"}]); 243 | 244 | // Real world example - records with a status of active or pending 245 | db([{status:"Active"},{status:"Pending"}]); 246 |247 |
A real world example of a complex query.
249 |// return records where the role is Admin and the status is Active. 250 | // Also return records where the role is Admin, the status is Pending, and the manager_review is true 251 | 252 | db({role:"Admin"},[{status:"Active"},{status:"Pending",manager_review:true}]); 253 |254 |
In addition to the default "is" operator there are a lot of other operators you can use to lookup records.
256 |259 | is 260 | | 261 |
262 | Example: {column:{is:value}} 263 | |
264 | 265 | Used to see if a column is of same type and value of supplied value. 266 | | 267 |
270 | == 271 | | 272 |
273 | Example: {column:{'==':value}} 274 | |
275 | 276 | Used to see if a column matches a supplied value using JavaScript's liberal coercion rules. 277 | | 278 |
281 | === 282 | | 283 |
284 | Example: {column:{'===':value}} 285 | |
286 | 287 | Used to see if a column is of same type and value of supplied value. 288 | | 289 |
292 | isnocase 293 | | 294 |
295 | Example: {column:{isnocase:value}} 296 | |
297 | 298 | Used to see if a column value is equal to a supplied value. Ignores case of column and value. 299 | | 300 |
303 | left 304 | | 305 |
306 | Example: {column:{left:value}} 307 | |
308 | 309 | Used to see if the start of a column is the same as a supplied value. 310 | | 311 |
314 | leftnocase 315 | | 316 |
317 | Example: {column:{leftnocase:value}} 318 | |
319 | 320 | Used to see if the start of a column is the same as a supplied value. Ignores case of column and value. 321 | | 322 |
325 | right 326 | | 327 |
328 | Example: {column:{right:value}} 329 | |
330 | 331 | Used to see if the end of a column is the same as a supplied value. 332 | | 333 |
336 | rightnocase 337 | | 338 |
339 | Example: {column:{rightnocase:value}} 340 | |
341 | 342 | Used to see if the end of a column is the same as a supplied value. Ignores case of column and value 343 | | 344 |
347 | like 348 | | 349 |
350 | Example: {column:{like:value}} 351 | |
352 | 353 | Used to see if column contains a supplied value. 354 | | 355 |
358 | likenocase 359 | | 360 |
361 | Example: {column:{likenocase:value}} 362 | |
363 | 364 | Used to see if column contains a supplied value. Ignores case of column and value 365 | | 366 |
369 | regex 370 | | 371 |
372 | Example: {column:{regex:value}} 373 | |
374 | 375 | Used to see if column matches a supplied regular expression. 376 | | 377 |
380 | lt 381 | | 382 |
383 | Example: {column:{lt:value}} or {column:{'<':value}} 384 | |
385 | 386 | Used to see if column is less than a supplied value. 387 | | 388 |
391 | lte 392 | | 393 |
394 | Example: {column:{lte:value}} or {column:{'<=':value}} 395 | |
396 | 397 | Used to see if column is less than or equal to a supplied value. 398 | | 399 |
402 | gt 403 | | 404 |
405 | Example: {column:{gt:value}} or {column:{'>':value}} 406 | |
407 | 408 | Used to see if column is greater than a supplied value. 409 | | 410 |
413 | gte 414 | | 415 |
416 | Example: {column:{gte:value}} or {column:{'>=':value}} 417 | |
418 | 419 | Used to see if column is greater than or equal to a supplied value. 420 | | 421 |
424 | has 425 | | 426 |
427 | Example: {column:{has:value}} 428 | |
429 | 430 | Used to see if column that is an object has a value or object appearing in its tree. 431 | | 432 |
435 | hasAll 436 | | 437 |
438 | Example: {column:{hasAll:value}} 439 | |
440 | 441 | Used to see if column that is an object has a value or object appearing in its tree. 442 | | 443 |
447 | isSameArray 448 | | 449 |
450 | Example: {column:{isSameArray:value}} 451 | |
452 | 453 | Used to see if column is an array and is the same as a supplied array. 454 | | 455 |
458 | isSameObject 459 | | 460 |
461 | Example: {column:{isSameObject:value}} 462 | |
463 | 464 | Used to see if column is an object and is the same as a supplied object. 465 | | 466 |
469 | isString 470 | | 471 |
472 | Example: {column:{isString:true}} 473 | |
474 | 475 | Used to see if column a string. 476 | | 477 |
480 | isNumber 481 | | 482 |
483 | Example: {column:{isNumber:true}} 484 | |
485 | 486 | Used to see if column a number. 487 | | 488 |
491 | isArray 492 | | 493 |
494 | Example: {column:{isArray:true}} 495 | |
496 | 497 | Used to see if column an array. 498 | | 499 |
502 | isObject 503 | | 504 |
505 | Example: {column:{isObject:true}} 506 | |
507 | 508 | Used to see if column an object. 509 | | 510 |
513 | isFunction 514 | | 515 |
516 | Example: {column:{isFunction:true}} 517 | |
518 | 519 | Used to see if column a function. 520 | | 521 |
524 | isBoolean 525 | | 526 |
527 | Example: {column:{isBoolean:true}} 528 | |
529 | 530 | Used to see if column a boolean (true/false). 531 | | 532 |
535 | isNull 536 | | 537 |
538 | Example: {column:{isNull:true}} 539 | |
540 | 541 | Used to see if column null. 542 | | 543 |
546 | isUndefined 547 | | 548 |
549 | Example: {column:{isUndefined:true}} 550 | |
551 | 552 | Used to see if column undefined. 553 | | 554 |