diff --git a/Caching/FileDb/FileDb.dll b/Caching/FileDb/FileDb.dll
new file mode 100644
index 00000000..73f4061b
Binary files /dev/null and b/Caching/FileDb/FileDb.dll differ
diff --git a/Caching/FileDb/FileDb.xml b/Caching/FileDb/FileDb.xml
new file mode 100644
index 00000000..4f7062c5
--- /dev/null
+++ b/Caching/FileDb/FileDb.xml
@@ -0,0 +1,1870 @@
+
+
+
+ FileDb
+
+
+
+
+ Represents an open FileDb database file. None of the FileDb classes are re-entrant -
+ access to the class objects must be syncronised by the calling application.
+
+
+
+
+
+ Constructor for FileDb
+
+
+
+
+
+ ToString override - returns the DB filename or a string indicating its a memory DB
+
+
+
+
+
+
+ Open the indicated database file.
+ If dbFileName is null an in-memory database will be created.
+
+ The filename of the database file to open.
+ It can be a fully qualified path or, if no path is specified the current folder will be used.
+ Indicates whether to open read only or not
+
+
+
+
+ Open the indicated database file for encryption. Encryption is "all or nothing",
+ meaning all records are either encrypted or not.
+ If dbFileName is null an in-memory database will be created.
+
+ The filename of the database file to open.
+ It can be a fully qualified path or, if no path is specified the current folder will be used.
+ A string value to use as the encryption key
+ Indicates whether to open read only or not
+
+
+
+
+ Close an open database.
+
+
+
+
+
+ Create a new database file. If the file exists, it will be overwritten.
+ If dbFileName is null an in-memory database will be created.
+
+ The full pathname of the file or null/empty to create a memory DB
+ Array of Fields for the new database.
+
+
+
+
+ Create a new database file. If the file exists, it will be overwritten.
+ If dbFileName is null an in-memory database will be created.
+
+ The full pathname of the file or null/empty to create a memory DB
+ List of Fields for the new database.
+
+
+
+
+ Delete an existing database.
+
+ The pathname of the file to delete.
+ TODO: make static
+
+
+
+ Indicates if the DB filename's existence
+
+
+ True if the file exists, false otherwise
+
+
+
+
+ Start a transaction - a backup of the whole database file is made until the transaction is completed.
+ Be sure to call either CommitTrans or RollbackTrans so the backup can be disposed
+
+
+
+
+
+ Commit the changes since the transaction was begun
+
+
+
+
+
+ Roll back the changes since the transaction was begun
+
+
+
+
+
+ Add a new record to the database using the name-value pairs in the FieldValues object.
+ Note that not all fields must be represented. Missing fields will be set to default
+ values (0, empty or null). Note that only Array datatypes can NULL.
+
+ The name-value pairs to add.
+ The volatile index of the newly added record.
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpression representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified fields.
+
+
+
+
+ Get all records matching the search expression in the indicated order, if any.
+
+ Represents a single search expression, such as ID = 3
+ The list of fields to return or null for all fields
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex.
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpressionGroup representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields in the specified order
+
+
+
+
+ Get all records matching the FilterExpressionGroup in the indicated order, if any.
+
+ Represents a compound search expression, such as FirstName = "John" AND LastName = "Smith"
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified list
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return all records in the database (table).
+
+ A table containing all Records and Fields.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of Fields to return or null for all Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ Specify whether to include the Record index as one of the Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all Records and the specified Fields.
+
+
+
+
+ Sometimes you may need to get an empty table just for the field definitions.
+ Use this method because its much more efficient than using a contrived filter
+ which is designed to return no results.
+
+ An empty table containing all fields
+
+
+
+
+ Returns a single Record object at the current location. Meant to be used ONLY in conjunction
+ with the MoveFirst/MoveNext methods.
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A Record object or null
+
+
+
+
+
+ Returns a single Record object specified by the index.
+
+ The index of the record to return. This value can be obtained from
+ Record returning queries by specifying true for the includeIndex parameter.
+ The list of fields to return or null for all fields
+ A Record object or null
+
+
+
+
+ Returns a single Record object specified by the primary key value or record number.
+
+ The primary key value. For databases without a primary key,
+ 'key' is the zero-based record number in the table.
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A Record object or null
+
+
+
+
+ Update the record at the indicated index. To get the index, you would need to first
+ get a record from the database then use the index field from it. The index is only
+ valid until a database operation which would invalidate it, such as adding/deleting
+ a record, or changing the value of a primary key.
+
+ The record values to update
+ The index of the record to update
+
+
+
+
+ Update the record with the indicated primary key value.
+
+ The record values to update
+ The primary key value of the record to update
+
+
+
+
+ Update all records which match the search criteria using the values in record.
+
+ The search expression, e.g. ID = 100
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Update all records which match the compound search criteria using the values in record.
+
+ The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Update all records which match the filter expression using the values in record.
+
+ The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
+ This filter string will be parsed using FilterExpressionGroup.Parse.
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Delete all records in the database
+
+ The number of records deleted
+
+
+
+
+ Delete the record at the specified index. You would normally get the index from a previous
+ query. This index is only valid until a record has been deleted.
+
+ The zero-based index of the record to delete.
+ true if the record was deleted, false otherwise
+
+
+
+
+ Delete the record with the specified primary key value
+
+ The primary key value of the record to delete
+ true if the record was deleted, false otherwise
+
+
+
+
+ Delete all records which match the search criteria.
+
+ The search expression, e.g. ID = 100
+ The number of records deleted
+
+
+
+
+ Delete all records which match the compound search criteria.
+
+ The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
+ The number of records deleted
+
+
+
+
+ Delete all records which match the filter criteria.
+
+ The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
+ This filter string will be parsed using FilterExpressionGroup.Parse.
+ The number of records deleted
+
+
+
+
+ Move to the first record in the index. Use this in conjunction with MoveNext and GetCurrentRecord
+
+
+
+
+
+ Move to the next record in the index. Use this in conjunction with MoveFirst and GetCurrentRecord
+
+
+
+
+ Call this to remove deleted records from the file (compact).
+
+
+
+
+
+ Call this to write the index and flush the stream buffer to disk.
+ Flushing will be done automatically if AutoFlush is On (and only writes the index
+ if necessary), whereas this call always writes the index.
+ You can use this to periodically write everything to disk rather than each time
+ as with AutoFlush. Flush is always called when the file is closed, however in that
+ case the index is only written if AutoFlush is set to Off.
+
+
+
+
+
+ Call this method to reindex the database if your index file should be deleted or corrupted.
+
+
+
+
+
+ Add the specified Field to the database.
+
+ The new Field to add
+ A default value to use for the values of existing records for the new Field
+
+
+
+
+ Add the specified Field to the database.
+
+ The new Fields to add
+ Default values to use for the values of existing records for the new Fields.
+ Can be null but if not then you must provide a value for each field in the Fields array
+
+
+
+
+ Delete the specified Field from the database.
+
+ The name of the Field to delete
+
+
+
+
+ Delete the specified Fields from the database.
+
+ The Fields to delete
+
+
+
+
+ Rename the specified Field.
+
+ The name of the Field to rename
+
+
+
+
+ Allows you to set an encryption key after the database has been opened. You must set
+ the encryption key before reading or writing to the database. Encryption is "all or nothing",
+ meaning all records are either encrypted or not.
+
+ A string value to use as the encryption key
+
+
+
+
+ Encrypt a string value.
+ Not syncronized.
+
+ The key to use for encryption
+ The value to encrypt
+ The encrypted value as a string
+
+
+
+
+ Decrypt a string value.
+ Not syncronized.
+
+ The key to use for decryption
+ The value to decrypt
+ The decrypted value as a string
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter.
+
+ A FilterExpression representing the desired filter.
+ A new List of custom objects with the requested Records
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new List of custom objects with the requested Records and Fields ordered by the specified fields.
+
+
+
+
+ Get all records matching the search expression in the indicated order, if any.
+
+ Represents a single search expression, such as ID = 3
+ The list of fields to return or null for all fields
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex.
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter.
+
+ A FilterExpressionGroup representing the desired filter.
+ A new List of custom objects with the requested Records
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new List of custom objects with the requested Records and Fields in the specified order
+
+
+
+
+ Get all records matching the FilterExpressionGroup in the indicated order, if any.
+
+ Represents a compound search expression, such as FirstName = "John" AND LastName = "Smith"
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ A new List of custom objects with the requested Records
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new List of custom objects with the requested Records and Fields ordered by the specified list
+
+
+
+
+ Return a List of custom objects filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order
+ A new List of custom objects with the requested Records and Fields
+
+
+
+
+ Return all records in the database (table).
+
+ A table containing all Records and Fields.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of Fields to return or null for all Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ Specify whether to include the Record index as one of the Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all Records and the specified Fields.
+
+
+
+
+ Returns a single custom object at the current location. Meant to be used ONLY in conjunction
+ with the MoveFirst/MoveNext methods.
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A new object or null
+
+
+
+
+
+ Returns a single custom object specified by the index.
+
+ The index of the record to return. This value can be obtained from
+ Record returning queries by specifying true for the includeIndex parameter.
+ The list of fields to return or null for all fields
+ A new object or null
+
+
+
+
+ Returns a single custom object specified by the primary key value or record number.
+
+ The primary key value. For databases without a primary key,
+ 'key' is the zero-based record number in the table.
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A new object or null
+
+
+
+
+ Static event fired when a record has been updated.
+
+
+
+
+ Static event fired when a record has been inserted.
+
+
+
+
+ Static event fired when a record has been deleted.
+
+
+
+
+ Fired when a record has been updated.
+
+
+
+
+
+ Fired when a record has been inserted.
+
+
+
+
+
+ Fired when a record has been deleted.
+
+
+
+
+
+ The full filename of the DB file
+
+
+
+
+
+ A value which can be used to keep track of the database version for changes
+
+
+
+
+ The fields of the database (table).
+
+
+
+
+
+ The number of records in the database (table). Doesn't include deleted records.
+
+
+
+
+
+ The number of deleted records which not yet cleaned from the file. Call the
+ Clean method to remove all deleted records and compact the file.
+
+
+
+
+
+ Configures autoclean. When an edit or delete is made, the
+ record is normally not removed from the data file - only the index.
+ After repeated edits/deletions, the data file may become very big with
+ deleted (non-removed) records. A cleanup is normally done with the
+ cleanup() method. Autoclean will do this automatically, keeping the
+ number of deleted records to under the threshold value.
+ To turn off autoclean, set threshold to a negative value.
+
+
+
+
+
+ Specifies whether to automatically flush data buffers and write the index after each
+ operation in which the file was updated. When AutoFlush is not On, the index is not
+ written until the file is closed or Flush is called.
+ You can set AutoFlush to Off just before performing a bulk operation to dramatically
+ increase performance, then set it back On after. When you set it back On after it was
+ Off, everything is flushed immediately because the assumption is that it was needed,
+ so you don't need to call Flush in this case.
+
+ Setting AutoFlush On is most useful for when you aren't able to guarantee that you will
+ be able to call Close before the program closes. This way the file won't become corrupt
+ in this case.
+
+
+
+
+
+ Tests to see if a database is currently open.
+
+
+
+
+
+ Allow ability to store meta data in the DB file. MetaData must be one of the supported
+ DataTypes: String, Byte, Int, UInt, Float, Double, Bool, DateTime and also Byte[]
+
+
+
+
+
+ Handler for static DbRecordUpdated event.
+
+ The name of the updated database
+ The record index
+ The fields and new values which were updated
+
+
+
+
+ Handler for static DbRecordAdded event.
+
+ The name of the updated database
+ The record index
+
+
+
+ Handler for static DbRecordDeleted event.
+
+ The name of the updated database
+ The record index
+
+
+
+ Handler for RecordUpdated event.
+
+ The record index
+ The fields and new values which were updated
+
+
+
+
+ Handler for RecordAdded event.
+
+ The record index
+
+
+
+
+ Handler for RecordDeleted event.
+
+ The record index
+
+
+
+
+ Specifies the data type for database Fields
+
+
+
+
+
+ Specifies the type of match for FilterExpressions with String data types
+
+
+
+
+ Specifies the comparison operator to use for FilterExpressions
+
+
+
+
+ Boolean operands to use to join FilterExpressions
+
+
+
+
+ Constructor
+
+
+
+
+ Open the database files
+
+
+
+
+
+
+
+ Flushes the Stream and detaches it, rendering this FileDb closed
+
+
+
+
+ ----------------------------------------------------------------------------------------
+
+ record must have all fields
+
+
+
+
+ ----------------------------------------------------------------------------------------
+
+ record must have all fields
+
+
+
+
+
+ Configures autoclean. When an edit or delete is made, the
+ record is normally not removed from the data file - only the index.
+ After repeated edits/deletions, the data file may become very big with
+ deleted (non-removed) records. A cleanup is normally done with the
+ cleanup() method. Autoclean will do this automatically, keeping the
+ number of deleted records to under the threshold value.
+ To turn off autoclean, set threshold to a negative value.
+
+ number of deleted records to have at any one time
+
+
+
+ ----------------------------------------------------------------------------------------
+
+ Read all records to create new index.
+
+
+
+
+
+ Remove all deleted records
+
+
+
+
+
+ Removes an entry from the database INDEX only - it appears
+ deleted, but the actual data is only removed from the file when a
+ cleanup() is called.
+
+ Int32 or string primary key used to identify record to remove. For
+ databases without primary keys, it is the record number (zero based) in
+ the table.
+ true if a record was removed, false otherwise
+
+
+
+
+ Removes an entry from the database INDEX only - it appears
+ deleted, but the actual data is only removed from the file when a
+ cleanup() is called.
+
+ The record number (zero based) in the table to remove
+ true on success, false otherwise
+
+
+
+
+ Removes entries from the database INDEX only, based on the
+ result of a regular expression match on a given field - records appear
+ deleted, but the actual data is only removed from the file when a
+ cleanup() is called.
+
+
+ number of records removed
+
+
+
+ move to the first index position
+
+
+
+
+
+ Move the current index position to the next database item.
+
+ true if advanced to a new item, false if there are none left
+
+
+
+
+ Return the current record in the database. Note that the current iterator pointer is not moved in any way.
+
+
+
+
+
+
+ retrieves a record based on the specified key
+
+ primary key used to identify record to retrieve. For
+ databases without primary keys, it is the record number (zero based) in
+ the table.
+
+ if true, an extra field called 'IFIELD' will
+ be added to each record returned. It will contain an Int32 that specifies
+ the original position in the database (zero based) that the record is
+ positioned. It might be useful when an orderby is used, and a future
+ operation on a record is required, given it's index in the table.
+ record if found, or false otherwise
+
+
+
+
+ retrieves a record based on the record number in the table
+ (zero based)
+
+ zero based record number to retrieve
+
+
+
+
+
+
+
+ Searches the database for an item, and returns true if found, false otherwise.
+
+ rimary key of record to search for, or the record
+ number (zero based) for databases without a primary key
+ true if found, false otherwise
+
+
+
+
+ Returns the number of records in the database
+
+ the number of records in the database
+
+
+
+
+ Returns the number of deleted records in the database, that would be removed if cleanup() is called.
+
+ the number of deleted records in the database
+
+
+
+
+ Returns the current database schema in the same form
+ as that used in the parameter for the create(...) method.
+
+
+
+
+
+
+ Flush the in-memory buffers to disk
+
+
+
+
+
+ Helper
+
+
+
+
+
+
+
+ Helper
+
+
+
+
+
+
+
+ Use this version if you will need to add/remove indices
+
+
+
+
+
+ function to write the index values. We assume the
+ database has been locked before calling this function.
+
+
+
+
+
+
+
+
+
+
+ to keep track of null fields in written record
+
+
+
+
+
+ Use this version only if all of the fields are present and in the correct order in the array
+
+
+
+
+
+
+
+
+ Use this version only if all of the fields are present and in the correct order in the array
+
+
+
+
+
+
+ Write a single field to the file
+
+
+
+
+
+
+
+ ------------------------------------------------------------------------------
+
+ Private function to perform a binary search
+
+ file offsets into the .dat file, it must be ordered
+ by primary key.
+ the left most index to start searching from
+ the right most index to start searching from
+ the search target we're looking for
+ -[insert pos+1] when not found, or the array index+1
+ when found. Note that we don't return the normal position, because we
+ can't differentiate between -0 and +0.
+
+
+
+
+ Helper
+
+
+
+
+
+
+
+ Private function to read a record from the database
+
+
+
+
+
+ size does not include the 4 byte record length, but only the total size of the fields
+
+
+
+
+
+
+
+
+ function to read a record KEY from the database. Note
+ that this function relies on the fact that they key is ALWAYS the first
+ item in the database record as stored on disk.
+
+
+
+
+
+
+
+
+ Reads a data type from a file. Note that arrays can only
+ consist of other arrays, ints, and strings.
+
+
+
+
+
+
+
+
+ Write the database schema and other meta information.
+
+
+
+
+
+
+ Helper
+
+
+
+
+
+
+
+ Use this class for single field searches.
+
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+ The match type, eg. MatchType.Exact
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+ The match type, eg. MatchType.Exact
+ Operator negation
+
+
+
+
+ Parse the expression string to create a FilterExpressionGroup representing a simple expression.
+
+ The string expression. Example: LastName = 'Fuller'
+ A new FilterExpression representing the simple expression
+
+
+
+
+ Utility method to transform a filesystem wildcard pattern into a regex pattern
+ eg. december* or mary?
+
+
+
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A Table to use to build the IN FilterExpressions
+ The name of the Field in the Table which holds the value to be used to build the IN FilterExpressions
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of custom objects to use to build the IN FilterExpression
+ The name of the Property of the custom class which holds the value to be
+ used to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of strings to use to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of strings to use to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Use this class to group FilterExpression and FilterExpressionGroup to form compound search expressions.
+ All expressions in the group will be evaluated by the same boolean And/Or operation. Use multiple
+ FilterExpressionGroups to form any combination of And/Or logic.
+
+
+
+
+
+ Parse the expression string to create a FilterExpressionGroup representing a compound expression.
+
+ The string compound expression. Example: (FirstName ~= 'andrew' OR FirstName ~= 'nancy') AND LastName = 'Fuller'
+ A new FilterExpressionGroup representing the compound expression
+
+
+
+
+ Summary description for HexEncoding.
+
+
+
+
+ Creates a byte array from the hexadecimal string. Each two characters are combined
+ to create one byte. First two hexadecimal characters become first byte in returned array.
+ Non-hexadecimal characters are ignored.
+
+ string to convert to byte array
+ number of characters in string ignored
+ byte array, in the same left-to-right order as the hexString
+
+
+
+ Determines if given string is in proper hexadecimal string format
+
+
+
+
+
+
+ Returns true is c is a hexadecimal digit (A-F, a-f, 0-9)
+
+ Character to test
+ true if hex digit, false if not
+
+
+
+ Converts 1 or 2 character string into equivalant byte value
+
+ 1 or 2 character string
+ byte
+
+
+
+ Represents a column of the database (table).
+
+
+
+
+ Use this constructor when creating a new database. The ordinal index of the field will be the
+ order it was added to the field list, unless a primary key field is specified and wasn't the
+ first in the list. In this case the primary key field will be moved to the first in the list
+ so that its always first.
+
+ The name of the field
+ The data type of the field
+
+
+
+
+ Use this constructor when you need to create a Records list manually rather than
+ using one retured from a query. In this case, you must set the field ordinal index
+ for each field, starting at zero.
+
+ The name of the field
+ The data type of the field
+ The zero-based ordinal index of the field
+
+
+
+
+ Clone this Field
+
+ A new Field with the same values
+
+
+
+ The name of the field.
+
+
+
+
+ The type of the field.
+
+
+
+
+ The zero-based ordinal index of the field.
+
+
+
+
+ Indicates if this is the one and only primary key field
+
+
+
+
+ Indicate if this is an Array type field
+
+
+
+
+ Used for auto-increment fields. Set to the number which you want incrementing to begin.
+ Leave it null if not an auto-increment field.
+
+
+
+
+ Returns true if this is an auto-increment field, false otherwise
+
+
+
+
+ Comment for the field
+
+
+
+
+ User property to associate a value with this Field
+
+
+
+
+ Represents data for a row, a Record consists of name-value pairs.
+ Used when adding data to the database and by the Record object
+ to store data returned from queries.
+
+
+
+
+ Represents a single row returned from a query. It will
+ contain one or more fields of the database (table). The last column may be the index of the row (if requested),
+ which is the zero-based position of the record in the index. If there is no primary key specified for
+ the database (table), then the index is the record number in the order in which the row was added to the database.
+
+
+
+
+
+ Create a Record object with the indicated Fields and values. If creating a list of Record objects
+ (for a Records list) be sure to use the same Fields list for each Record.
+
+ List of Field objects
+ Array of values. Each value will be converted to the Field type if possible.
+
+
+
+
+ Create a Record object with the indicated Fields and values. If creating a list of Record objects
+ (for a Records list) be sure to use the same Fields list for each Record.
+
+ List of Field objects
+ Array of values. Each value will be converted to the Field type if possible.
+
+
+
+
+ Tests to see if the indicated field is in this Record
+
+
+ true if the field is in this Record
+
+
+
+
+ Return the Typed field value.
+
+ The name of the field
+ The Type field value
+
+
+
+
+ Return the integer field value.
+
+ The name of the field
+ The integer field value
+
+
+
+
+ Return the integer field value.
+
+ The ordinal index of the field
+ The integer field value
+
+
+
+
+ Return the unsigned integer field value.
+
+ The name of the field
+ The unsigned integer field value
+
+
+
+
+ Return the unsigned integer field value.
+
+ The ordinal index of the field
+ The unsigned integer field value
+
+
+
+
+ Return the String field value.
+
+ The name of the field
+ The String field value
+
+
+
+
+ Return the String field value.
+
+ The ordinal index of the field
+ The String field value
+
+
+
+
+ Return the Byte field value.
+
+ The name of the field
+ The Byte field value
+
+
+
+
+ Return the Byte field value.
+
+ The ordinal index of the field
+ The Byte field value
+
+
+
+
+ Return the Single field value.
+
+ The name of the field
+ The Single field value
+
+
+
+
+ Return the Single field value.
+
+ The ordinal index of the field
+ The Single field value
+
+
+
+
+ Return the Double field value.
+
+ The name of the field
+ The Double field value
+
+
+
+
+ Return the Decimal field value.
+
+ The ordinal index of the field
+ The Decimal field value
+
+
+
+
+ Return the Decimal field value.
+
+ The name of the field
+ The Decimal field value
+
+
+
+
+ Return the Double field value.
+
+ The ordinal index of the field
+ The Double field value
+
+
+
+
+ Return the Boolean field value.
+
+ The name of the field
+ The Boolean field value
+
+
+
+
+ Return the Boolean field value.
+
+ The ordinal index of the field
+ The Boolean field value
+
+
+
+
+ Return the DateTime field value.
+
+ The name of the field
+ The DateTime field value
+
+
+
+
+ Return the DateTime field value.
+
+ The ordinal index of the field
+ The DateTime field value
+
+
+
+
+ The number of fields in the Record
+
+
+
+
+
+ A property which is used for integrating with the binding framework.
+
+
+
+
+
+ Used by the Record class for enumerating in foreach contructs
+
+
+
+
+
+ A List of Records
+
+
+
+
+
+ A list of Fields
+
+
+
+
+
+ Represents a data table returned from a query. A table is made up of Fields and Records.
+
+
+
+
+
+ Create a table with the indicated Fields.
+
+ The Fields list to use (a copy is made)
+
+
+
+
+ Create a table with the indicated Fields and records. If copyFields is true, a new
+ Fields list is created and a copy of each field is made and its ordinal adjusted.
+ Otherwise the original Fields object is adopted. You should pass false for copyFields
+ only if you created the Fields list and its Field objects yourself.
+
+ The Fields list to use
+ Indicates whether to make a copy of the Fields object and each Field.
+
+
+
+
+ Create a table with the indicated Fields and records. If copyFields is true, a new
+ Fields list is created and a copy of each field is made and its ordinal adjusted.
+ Otherwise the original Fields object is adopted. You should pass false for copyFields
+ only if you created the Fields list and its Field objects yourself.
+
+ The Fields list to use
+ The record data
+ Indicates whether to make a copy of the Fields object and each Field.
+
+
+
+
+ Create a table with the indicated Fields and records. If copyFields is true, a new
+ Fields list is created and a copy of each field is made and its ordinal adjusted.
+ Otherwise the original Fields object is adopted. You should pass false for copyFields
+ only if you created the Fields list and its Field objects yourself and the Fields in
+ the Record objects match the data in the Record.
+
+ The Fields list to use
+ The record data
+ Indicates whether to make a copy of the Fields object and each Field.
+
+
+
+
+ Add a new Record to this Table with all null values.
+
+
+
+
+
+
+ Add a new Record to this Table with the specfied values, which must be in the order
+ of their corresponding fields.
+
+
+
+
+
+
+ Add a new Record to this Table with the FieldValues
+
+
+
+
+
+
+
+ Save this Table to the indicated file as a new database. If the file exists
+ it will be overwritten. The new database will be just as if you had created
+ it from scratch and populated it with the Table data.
+
+ The full path and filename of the new database
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified list
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpression representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified fields.
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpressionGroup representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields in the specified order
+
+
+
+
+ The Fields of the Table
+
+
+
+
+
+ A simple class used to communicate property value changes to a Record.
+ Used by WPF databinding.
+
+
+
+
+
diff --git a/Caching/FileDb/FileDbPcl.dll b/Caching/FileDb/FileDbPcl.dll
new file mode 100644
index 00000000..1789b1ce
Binary files /dev/null and b/Caching/FileDb/FileDbPcl.dll differ
diff --git a/Caching/FileDbCache/FileDb/FileDb.XML b/Caching/FileDb/FileDbPcl.xml
similarity index 83%
rename from Caching/FileDbCache/FileDb/FileDb.XML
rename to Caching/FileDb/FileDbPcl.xml
index 47c4a542..3c65bc3d 100644
--- a/Caching/FileDbCache/FileDb/FileDb.XML
+++ b/Caching/FileDb/FileDbPcl.xml
@@ -1,7 +1,7 @@
- FileDb
+ FileDbPcl
@@ -10,6 +10,495 @@
access to the class objects must be syncronised by the calling application.
+
+
+
+ Constructor for FileDb
+
+
+
+
+
+ ToString override - returns the DB filename or a string indicating its a memory DB
+
+
+
+
+
+
+ Open with an existing database stream
+
+ The database stream to use - normally a FileStream
+
+
+
+
+ Close an open database.
+
+
+
+
+
+ Create a new database using the passed stream, or if null and in-memory DB
+
+ The stream to use or null to create a memory DB
+ Array of Fields for the new database.
+
+
+
+
+ Create a new database using the passed stream, or if null and in-memory DB
+
+ The stream to use or null to create a memory DB
+ List of Fields for the new database.
+
+
+
+
+ Start a transaction - a backup of the whole database file is made until the transaction is completed.
+ Be sure to call either CommitTrans or RollbackTrans so the backup can be disposed
+
+
+
+
+
+ Commit the changes since the transaction was begun
+
+
+
+
+
+ Roll back the changes since the transaction was begun
+
+
+
+
+
+ Add a new record to the database using the name-value pairs in the FieldValues object.
+ Note that not all fields must be represented. Missing fields will be set to default
+ values (0, empty or null). Note that only Array datatypes can NULL.
+
+ The name-value pairs to add.
+ The volatile index of the newly added record.
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpression representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified fields.
+
+
+
+
+ Get all records matching the search expression in the indicated order, if any.
+
+ Represents a single search expression, such as ID = 3
+ The list of fields to return or null for all fields
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex.
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A FilterExpressionGroup representing the desired filter.
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A FilterExpression representing the desired filter.
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields in the specified order
+
+
+
+
+ Get all records matching the FilterExpressionGroup in the indicated order, if any.
+
+ Represents a compound search expression, such as FirstName = "John" AND LastName = "Smith"
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ A new Table with the requested Records
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return a Table of Records filtered by the filter parameter. Only the specified Fields
+ will be in the Table.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order.
+ A new Table with the requested Records and Fields ordered by the specified list
+
+
+
+
+ Return a Table of Records filtered by the filter parameter.
+
+ A string representing the desired filter, eg. LastName = 'Fuller'
+ The desired fields to be in the returned Table
+ If true, an additional Field named "index" will be returned
+ which is the ordinal index of the Record in the database, which can be used in
+ GetRecordByIndex and UpdateRecordByIndex
+ A list of one or more fields to order the returned table by,
+ or null for default order. If an orderByField is prefixed with "!", that field will sorted
+ in reverse order
+ A new Table with the requested Records and Fields
+
+
+
+
+ Return all records in the database (table).
+
+ A table containing all Records and Fields.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of Fields to return or null for all Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ Specify whether to include the Record index as one of the Fields
+ A table containing all rows.
+
+
+
+
+ Return all records in the database (table).
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A list of one or more fields to order the returned table by,
+ or null for default order
+ A table containing all Records and the specified Fields.
+
+
+
+
+ Sometimes you may need to get an empty table just for the field definitions.
+ Use this method because its much more efficient than using a contrived filter
+ which is designed to return no results.
+
+ An empty table containing all fields
+
+
+
+
+ Returns a single Record object at the current location. Meant to be used ONLY in conjunction
+ with the MoveFirst/MoveNext methods.
+
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A Record object or null
+
+
+
+
+
+ Returns a single Record object specified by the index.
+
+ The index of the record to return. This value can be obtained from
+ Record returning queries by specifying true for the includeIndex parameter.
+ The list of fields to return or null for all fields
+ A Record object or null
+
+
+
+
+ Returns a single Record object specified by the primary key value or record number.
+
+ The primary key value. For databases without a primary key,
+ 'key' is the zero-based record number in the table.
+ The list of fields to return or null for all fields
+ Specify whether to include the record index as one of the Fields
+ A Record object or null
+
+
+
+
+ Update the record at the indicated index. To get the index, you would need to first
+ get a record from the database then use the index field from it. The index is only
+ valid until a database operation which would invalidate it, such as adding/deleting
+ a record, or changing the value of a primary key.
+
+ The record values to update
+ The index of the record to update
+
+
+
+
+ Update the record with the indicated primary key value.
+
+ The record values to update
+ The primary key value of the record to update
+
+
+
+
+ Update all records which match the search criteria using the values in record.
+
+ The search expression, e.g. ID = 100
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Update all records which match the compound search criteria using the values in record.
+
+ The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Update all records which match the filter expression using the values in record.
+
+ The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
+ This filter string will be parsed using FilterExpressionGroup.Parse.
+ A list of name-value pairs to use to update the matching records
+ The number of records which were updated.
+
+
+
+
+ Delete all records in the database
+
+ The number of records deleted
+
+
+
+
+ Delete the record at the specified index. You would normally get the index from a previous
+ query. This index is only valid until a record has been deleted.
+
+ The zero-based index of the record to delete.
+ true if the record was deleted, false otherwise
+
+
+
+
+ Delete the record with the specified primary key value
+
+ The primary key value of the record to delete
+ true if the record was deleted, false otherwise
+
+
+
+
+ Delete all records which match the search criteria.
+
+ The search expression, e.g. ID = 100
+ The number of records deleted
+
+
+
+
+ Delete all records which match the compound search criteria.
+
+ The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
+ The number of records deleted
+
+
+
+
+ Delete all records which match the filter criteria.
+
+ The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
+ This filter string will be parsed using FilterExpressionGroup.Parse.
+ The number of records deleted
+
+
+
+
+ Move to the first record in the index. Use this in conjunction with MoveNext and GetCurrentRecord
+
+
+
+
+
+ Move to the next record in the index. Use this in conjunction with MoveFirst and GetCurrentRecord
+
+
+
+
+ Call this to remove deleted records from the file (compact).
+
+
+
+
+
+ Call this to write the index and flush the stream buffer to disk.
+ Flushing will be done automatically if AutoFlush is On (and only writes the index
+ if necessary), whereas this call always writes the index.
+ You can use this to periodically write everything to disk rather than each time
+ as with AutoFlush. Flush is always called when the file is closed, however in that
+ case the index is only written if AutoFlush is set to Off.
+
+
+
+
+
+ Call this method to reindex the database if your index file should be deleted or corrupted.
+
+
+
+
+
+ Add the specified Field to the database.
+
+ The new Field to add
+ A default value to use for the values of existing records for the new Field
+
+
+
+
+ Add the specified Field to the database.
+
+ The new Fields to add
+ Default values to use for the values of existing records for the new Fields.
+ Can be null but if not then you must provide a value for each field in the Fields array
+
+
+
+
+ Delete the specified Field from the database.
+
+ The name of the Field to delete
+
+
+
+
+ Delete the specified Fields from the database.
+
+ The Fields to delete
+
+
+
+
+ Rename the specified Field.
+
+ The name of the Field to rename
+
+
+
+
+ Allows you to set an encryption key after the database has been opened. You must set
+ the encryption key before reading or writing to the database. Encryption is "all or nothing",
+ meaning all records are either encrypted or not.
+
+ A string value to use as the encryption key
+
+
+
+
+ Encrypt a string value.
+ Not syncronized.
+
+ The key to use for encryption
+ The value to encrypt
+ The encrypted value as a string
+
+
+
+
+ Decrypt a string value.
+ Not syncronized.
+
+ The key to use for decryption
+ The value to decrypt
+ The decrypted value as a string
+
@@ -223,422 +712,48 @@
A new object or null
-
+
- Open the indicated database file.
+ Static event fired when a record has been updated.
- The filename of the database file to open. It can be a fully qualified
- path or, if no path is specified the current folder will be used.
-
-
+
- Open the indicated database file for encryption. Encryption is "all or nothing",
- meaning all records are either encrypted or not.
+ Static event fired when a record has been inserted.
- The filename of the database file to open. It can be a fully qualified
- path or, if no path is specified the current folder will be used.
- A string value to use as the encryption key
-
-
+
- Close an open database.
+ Static event fired when a record has been deleted.
+
+
+
+
+ Fired when a record has been updated.
-
+
- Create a new database file. If the file exists, it will be overwritten.
-
- The full pathname of the file.
- Array of Fields for the new database.
-
-
-
-
- Delete an existing database.
-
- The pathname of the file to delete.
-
-
-
-
- Add a new record to the database using the name-value pairs in the FieldValues object.
- Note that not all fields must be represented. Missing fields will be set to default
- values (0, empty or null). Note that only Array datatypes can NULL.
-
- The name-value pairs to add.
- The volatile index of the newly added record.
-
-
-
-
- Return a Table of Records filtered by the filter parameter.
-
- A FilterExpression representing the desired filter.
- A new Table with the requested Records
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A FilterExpression representing the desired filter.
- The desired fields to be in the returned Table
- A new Table with the requested Records and Fields
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A FilterExpression representing the desired filter.
- The desired fields to be in the returned Table
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order.
- A new Table with the requested Records and Fields ordered by the specified fields.
-
-
-
-
- Get all records matching the search expression in the indicated order, if any.
-
- Represents a single search expression, such as ID = 3
- The list of fields to return or null for all fields
- If true, an additional Field named "index" will be returned
- which is the ordinal index of the Record in the database, which can be used in
- GetRecordByIndex and UpdateRecordByIndex.
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order.
- A new Table with the requested Records and Fields
-
-
-
-
- Return a Table of Records filtered by the filter parameter.
-
- A FilterExpressionGroup representing the desired filter.
- A new Table with the requested Records
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A FilterExpression representing the desired filter.
- The desired fields to be in the returned Table
- A new Table with the requested Records and Fields
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A FilterExpression representing the desired filter.
- The desired fields to be in the returned Table
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order.
- A new Table with the requested Records and Fields in the specified order
-
-
-
-
- Get all records matching the FilterExpressionGroup in the indicated order, if any.
-
- Represents a compound search expression, such as FirstName = "John" AND LastName = "Smith"
- The list of fields to return or null for all fields
- Specify whether to include the record index as one of the Fields
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order.
- A new Table with the requested Records and Fields
-
-
-
-
- Return a Table of Records filtered by the filter parameter.
-
- A string representing the desired filter, eg. LastName = 'Fuller'
- A new Table with the requested Records
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A string representing the desired filter, eg. LastName = 'Fuller'
- The desired fields to be in the returned Table
- A new Table with the requested Records and Fields
-
-
-
-
- Return a Table of Records filtered by the filter parameter. Only the specified Fields
- will be in the Table.
-
- A string representing the desired filter, eg. LastName = 'Fuller'
- The desired fields to be in the returned Table
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order.
- A new Table with the requested Records and Fields ordered by the specified list
-
-
-
-
- Return a Table of Records filtered by the filter parameter.
-
- A string representing the desired filter, eg. LastName = 'Fuller'
- The desired fields to be in the returned Table
- If true, an additional Field named "index" will be returned
- which is the ordinal index of the Record in the database, which can be used in
- GetRecordByIndex and UpdateRecordByIndex
- A list of one or more fields to order the returned table by,
- or null for default order. If an orderByField is prefixed with "!", that field will sorted
- in reverse order
- A new Table with the requested Records and Fields
-
-
-
-
- Return all records in the database (table).
-
- A table containing all Records and Fields.
-
-
-
-
- Return all records in the database (table).
-
- The list of Fields to return or null for all Fields
- A table containing all rows.
-
-
-
-
- Return all records in the database (table).
-
- The list of fields to return or null for all Fields
- A list of one or more fields to order the returned table by,
- or null for default order
- A table containing all rows.
-
-
-
-
- Return all records in the database (table).
-
- Specify whether to include the Record index as one of the Fields
- A table containing all rows.
-
-
-
-
- Return all records in the database (table).
-
- The list of fields to return or null for all fields
- Specify whether to include the record index as one of the Fields
- A list of one or more fields to order the returned table by,
- or null for default order
- A table containing all Records and the specified Fields.
-
-
-
-
- Returns a single Record object at the current location. Meant to be used ONLY in conjunction
- with the MoveFirst/MoveNext methods.
-
- The list of fields to return or null for all fields
- Specify whether to include the record index as one of the Fields
- A Record object or null
-
-
-
-
-
- Returns a single Record object specified by the index.
-
- The index of the record to return. This value can be obtained from
- Record returning queries by specifying true for the includeIndex parameter.
- The list of fields to return or null for all fields
- A Record object or null
-
-
-
-
- Returns a single Record object specified by the primary key value or record number.
-
- The primary key value. For databases without a primary key,
- 'key' is the zero-based record number in the table.
- The list of fields to return or null for all fields
- Specify whether to include the record index as one of the Fields
- A Record object or null
-
-
-
-
- Update the record at the indicated index. To get the index, you would need to first
- get a record from the database then use the index field from it. The index is only
- valid until a database operation which would invalidate it, such as adding/deleting
- a record, or changing the value of a primary key.
-
- The record values to update
- The index of the record to update
-
-
-
-
- Update the record with the indicated primary key value.
-
- The record values to update
- The primary key value of the record to update
-
-
-
-
- Update all records which match the search criteria using the values in record.
-
- The search expression, e.g. ID = 100
- A list of name-value pairs to use to update the matching records
- The number of records which were updated.
-
-
-
-
- Update all records which match the compound search criteria using the values in record.
-
- The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
- A list of name-value pairs to use to update the matching records
- The number of records which were updated.
-
-
-
-
- Update all records which match the filter expression using the values in record.
-
- The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
- This filter string will be parsed using FilterExpressionGroup.Parse.
- A list of name-value pairs to use to update the matching records
- The number of records which were updated.
-
-
-
-
- Delete the record at the specified index. You would normally get the index from a previous
- query. This index is only valid until a record has been deleted.
-
- The zero-based index of the record to delete.
- true if the record was deleted, false otherwise
-
-
-
-
- Delete the record with the specified primary key value
-
- The primary key value of the record to delete
- true if the record was deleted, false otherwise
-
-
-
-
- Delete all records which match the search criteria.
-
- The search expression, e.g. ID = 100
- The number of records deleted
-
-
-
-
- Delete all records which match the compound search criteria.
-
- The compound search expression, e.g. FirstName = "John" AND LastName = "Smith"
- The number of records deleted
-
-
-
-
- Delete all records which match the filter criteria.
-
- The filter to use, eg. "~LastName = 'peacock' OR ~FirstName = 'nancy'".
- This filter string will be parsed using FilterExpressionGroup.Parse.
- The number of records deleted
-
-
-
-
- Move to the first record in the index. Use this in conjunction with MoveNext and GetCurrentRecord
+ Fired when a record has been inserted.
-
+
- Move to the next record in the index. Use this in conjunction with MoveFirst and GetCurrentRecord
-
-
-
-
- Call this to remove deleted records from the file (compact).
+ Fired when a record has been deleted.
-
+
- Call this to write the index and flush the stream buffer to disk.
- Flushing will be done automatically if AutoFlush is On (and only writes the index
- if necessary), whereas this call always writes the index.
- You can use this to periodically write everything to disk rather than each time
- as with AutoFlush. Flush is always called when the file is closed, however in that
- case the index is only written if AutoFlush is set to Off.
+ The full filename of the DB file
-
-
-
- Call this method to reindex the database if your index file should be deleted or corrupted.
-
-
-
-
-
- Allows you to set an encryption key after the database has been opened. You must set
- the encryption key before reading or writing to the database. Encryption is "all or nothing",
- meaning all records are either encrypted or not.
-
- A string value to use as the encryption key
-
-
-
-
- Encrypt a string value.
- Not syncronized.
-
- The key to use for encryption
- The value to encrypt
- The encrypted value as a string
-
-
-
-
- Decrypt a string value.
- Not syncronized.
-
- The key to use for decryption
- The value to decrypt
- The decrypted value as a string
-
- A string value which can be used to keep track of the database version for changes
+ A value which can be used to keep track of the database version for changes
@@ -700,6 +815,51 @@
DataTypes: String, Byte, Int, UInt, Float, Double, Bool, DateTime and also Byte[]
+
+
+
+ Handler for static DbRecordUpdated event.
+
+ The name of the updated database
+ The record index
+ The fields and new values which were updated
+
+
+
+
+ Handler for static DbRecordAdded event.
+
+ The name of the updated database
+ The record index
+
+
+
+ Handler for static DbRecordDeleted event.
+
+ The name of the updated database
+ The record index
+
+
+
+ Handler for RecordUpdated event.
+
+ The record index
+ The fields and new values which were updated
+
+
+
+
+ Handler for RecordAdded event.
+
+ The record index
+
+
+
+
+ Handler for RecordDeleted event.
+
+ The record index
+
@@ -712,7 +872,7 @@
Specifies the type of match for FilterExpressions with String data types
-
+
Specifies the comparison operator to use for FilterExpressions
@@ -722,90 +882,24 @@
Boolean operands to use to join FilterExpressions
-
-
- Use this class for single field searches.
-
-
-
-
-
- Create a FilterExpression with the indicated values
-
- The name of the Field to filter on
- The Field value to filter on
- The Equality operator to use in the value comparison
-
-
-
-
- Create a FilterExpression with the indicated values
-
- The name of the Field to filter on
- The Field value to filter on
- The Equality operator to use in the value comparison
- The match type, eg. MatchType.Exact
-
-
-
-
- Parse the expression string to create a FilterExpressionGroup representing a simple expression.
-
- The string expression. Example: LastName = 'Fuller'
- A new FilterExpression representing the simple expression
-
-
-
-
- Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
- to filter the query.
-
- The name of the Field which will be used in the FilterExpressions
- A Table to use to build the IN FilterExpressions
- The name of the Field in the Table which holds the value to be used to build the IN FilterExpressions
- A new FilterExpression
-
-
-
-
- Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
- to filter the query.
-
- The name of the Field which will be used in the FilterExpressions
- A List of custom objects to use to build the IN FilterExpression
- The name of the Property of the custom class which holds the value to be
- used to build the IN FilterExpression
- A new FilterExpression
-
-
-
-
- Use this class to group FilterExpression and FilterExpressionGroup to form compound search expressions.
- All expressions in the group will be evaluated by the same boolean And/Or operation. Use multiple
- FilterExpressionGroups to form any combination of And/Or logic.
-
-
-
-
-
- Parse the expression string to create a FilterExpressionGroup representing a compound expression.
-
- The string compound expression. Example: (FirstName ~= 'andrew' OR FirstName ~= 'nancy') AND LastName = 'Fuller'
- A new FilterExpressionGroup representing the compound expression
-
-
Constructor
-
+
Open the database files
-
+
+
+
+
+ Flushes the Stream and detaches it, rendering this FileDb closed
+
+
----------------------------------------------------------------------------------------
@@ -865,7 +959,7 @@
deleted, but the actual data is only removed from the file when a
cleanup() is called.
- The record number (zero based) in the table to remove
+ The record number (zero based) in the table to remove
true on success, false otherwise
@@ -1101,6 +1195,118 @@
+
+
+
+ Use this class for single field searches.
+
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+ The match type, eg. MatchType.Exact
+
+
+
+
+ Create a FilterExpression with the indicated values
+
+ The name of the Field to filter on
+ The Field value to filter on
+ The Equality operator to use in the value comparison
+ The match type, eg. MatchType.Exact
+ Operator negation
+
+
+
+
+ Parse the expression string to create a FilterExpressionGroup representing a simple expression.
+
+ The string expression. Example: LastName = 'Fuller'
+ A new FilterExpression representing the simple expression
+
+
+
+
+ Utility method to transform a filesystem wildcard pattern into a regex pattern
+ eg. december* or mary?
+
+
+
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A Table to use to build the IN FilterExpressions
+ The name of the Field in the Table which holds the value to be used to build the IN FilterExpressions
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of custom objects to use to build the IN FilterExpression
+ The name of the Property of the custom class which holds the value to be
+ used to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of strings to use to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Create a FilterExpression of type "IN". This type is a HashSet of the values which will be used
+ to filter the query.
+
+ The name of the Field which will be used in the FilterExpressions
+ A List of strings to use to build the IN FilterExpression
+ A new FilterExpression
+
+
+
+
+ Use this class to group FilterExpression and FilterExpressionGroup to form compound search expressions.
+ All expressions in the group will be evaluated by the same boolean And/Or operation. Use multiple
+ FilterExpressionGroups to form any combination of And/Or logic.
+
+
+
+
+
+ Parse the expression string to create a FilterExpressionGroup representing a compound expression.
+
+ The string compound expression. Example: (FirstName ~= 'andrew' OR FirstName ~= 'nancy') AND LastName = 'Fuller'
+ A new FilterExpressionGroup representing the compound expression
+
@@ -1165,6 +1371,12 @@
The zero-based ordinal index of the field
+
+
+ Clone this Field
+
+ A new Field with the same values
+
The name of the field.
@@ -1193,7 +1405,7 @@
Used for auto-increment fields. Set to the number which you want incrementing to begin.
- Set to -1 if not an auto-increment field.
+ Leave it null if not an auto-increment field.
@@ -1232,8 +1444,17 @@
Create a Record object with the indicated Fields and values. If creating a list of Record objects
(for a Records list) be sure to use the same Fields list for each Record.
-
-
+ List of Field objects
+ Array of values. Each value will be converted to the Field type if possible.
+
+
+
+
+ Create a Record object with the indicated Fields and values. If creating a list of Record objects
+ (for a Records list) be sure to use the same Fields list for each Record.
+
+ List of Field objects
+ Array of values. Each value will be converted to the Field type if possible.
@@ -1244,7 +1465,15 @@
true if the field is in this Record
-
+
+
+ Return the Typed field value.
+
+ The name of the field
+ The Type field value
+
+
+
Return the integer field value.
@@ -1252,7 +1481,7 @@
The integer field value
-
+
Return the integer field value.
@@ -1260,7 +1489,7 @@
The integer field value
-
+
Return the unsigned integer field value.
@@ -1268,7 +1497,7 @@
The unsigned integer field value
-
+
Return the unsigned integer field value.
@@ -1331,6 +1560,22 @@
The name of the field
The Double field value
+
+
+
+ Return the Decimal field value.
+
+ The ordinal index of the field
+ The Decimal field value
+
+
+
+
+ Return the Decimal field value.
+
+ The name of the field
+ The Decimal field value
+
@@ -1407,6 +1652,24 @@
Represents a data table returned from a query. A table is made up of Fields and Records.
+
+
+
+ Create a table with the indicated Fields.
+
+ The Fields list to use (a copy is made)
+
+
+
+
+ Create a table with the indicated Fields and records. If copyFields is true, a new
+ Fields list is created and a copy of each field is made and its ordinal adjusted.
+ Otherwise the original Fields object is adopted. You should pass false for copyFields
+ only if you created the Fields list and its Field objects yourself.
+
+ The Fields list to use
+ Indicates whether to make a copy of the Fields object and each Field.
+
@@ -1433,21 +1696,36 @@
Indicates whether to make a copy of the Fields object and each Field.
-
+
- Create a new Record with all of the fields of the Table. The Record is not
- added to the Table. To do this, call Records.Add.
+ Add a new Record to this Table with all null values.
-
+
- Save this Table to the indicated file as a new database. If the file exists
- it will be overwritten. The new database will be just as if you had created
- it from scratch.
+ Add a new Record to this Table with the specfied values, which must be in the order
+ of their corresponding fields.
- The full path and filename of the new database
+
+
+
+
+
+ Add a new Record to this Table with the FieldValues
+
+
+
+
+
+
+
+ Save this Table to the Stream as a new database. If the Stream is null
+ one will be created and it will be a memory DB. The new database will be just as if you had created
+ it from scratch and populated it with the Table data.
+
+ The full path and filename of the new database
diff --git a/Caching/FileDb/Help.html b/Caching/FileDb/Help.html
new file mode 100644
index 00000000..c14fb2bd
--- /dev/null
+++ b/Caching/FileDb/Help.html
@@ -0,0 +1,983 @@
+
+
+
+
+
+FileDb Overview
+
+
+
+
+
+
Overview
+
+
FileDb is a simple database designed as a simple
+local database solution for Xamarin Cross-Platform phone (Android, IOS, WinPhone)
+or any .NET application. FileDb is a No-SQL database
+ meant for use as a local data store for applications.
+ Here are some important points about FileDb:
+
+
+
+ Stores one table per file, including its index
+
+ Extremely Lightweight - less than 50K
+
+ Supports field types Int, UInt, Bool, String, Byte,
+ Float, Double and DateTime and also arrays of the same
+ types
+
+ Index supports a single Primary Key field (optional)
+
+ Compiled versions for Windows Phone
+ RT/PCL,
+ .NET
+
+ FileDb is VERY FAST
+
+ FileDb is FREE to use in your applications
+
+ Use with LINQ to Objects to achieve full relational
+ capability
+
+
+
FileDb was specifically designed to use only native
+ .NET data types so there would no need to translate
+ between database storage and the CLR data types.
+ So you can just as easily read/write a String[] field as
+ you would an Int field. Another feature is that a
+ database file created on any .NET platform will work on
+ any other. So you can create a database file on
+ your Windows machine and it can be used in a Silverlight
+ or Windows Phone app.
+
+
LINQ + FileDb gives you full
+ relational database capability
+
Even though FileDb is a "flat-file" database, using
+ LINQ it becomes fully relational! LINQ
+ to Objects allows you to join Tables together just as
+ you would do in SQL. All of the power of LINQ is
+ available to you: Joins, Grouping, Sum - the lot.
+ (See
+ the examples below.)
+
FileDb also has a built-in
+ query filter parser so you can write SQL-like
+ filter expressions to make filtering data easy, like
+ this:
+
+
+
+ string filter = "FirstName IN ('Cindy', 'John') AND Age > 32"
+
+
Use FileDb in your .NET and mobile
+ applications where you need a searchable, updatable
+ local database.
+Use FileDb with Xamarin cross-platform app
+development
Most phone apps only require a
+simple database. By purchasing a source code license you can compile
+FileDb into your IOS, Android and Windows Phone projects and use the same exact
+data layer code for them all. This is much easier than using Sqlite
+wrappers. With FileDb's built in encryption you can have everything you
+need to have a secure data layer.
+
+FileDb Database Overview
+
+
FileDb is a simple database designed for use on any .NET platform such as Windows
+Phone and Silverlight, but its also great for any .NET app where simple local
+database storage is needed. For example, instead of using XML config files you
+could use a FileDb database to store and retrieve application data much more
+efficiently. FileDb allows only a single table per database file, so when we
+talk about a FileDb database we really mean a single table with an index. The
+index is stored in the file with the data, and allows an optional Primary Key.
+
FileDb is NOT a relational database - it is NO-SLQ,
+meaning you can't directly issue SQL commands for querying, adding or updating. However,
+you CAN use LINQ with
+FileDb to get full relational query capabilities. And FileDb does include an Expression Parser which parses SQL-like filter
+expressions, which makes searching, updating and deleting very easy - see below for an example.
+
And FileDb supports using powerful Regular Expressions for
+filtering.
+
FileDb supports AES encryption at the record level. This
+means the database schema is not encrypted (field names, etc.), but each record
+is entirely encrypted. Encryption is "all or nothing", meaning it expects that
+either all records are encrypted or all records are not encrypted. You turn
+encryption on by passing an encryption key when opening the database.
+
+
FileDb is thread-safe for multithreading environments, so it can be accessed from
+multiple threads at the same time without worrying about database corruption.
+
FileDb databases can only be opened by a single
+application. Any attempt to open the file when already open will fail.
+This makes sense since its meant for use by a single application at a time
+(FileDb is not meant as a multi-user database, such as SQL Server Express).
+
+
FileDb Classes
+
The main FileDb classes are: FileDb, Table,
+Field and Record.
+
+
+
FileDb
: Represents a database file. All database operations are
+ initiated through this class.
+
+
+
+
Table
: Represents a two
+ dimensional dataset returned from a query. A Table consists of Fields
+ and Records.
+
+
+
+
Field
: Defines the
+ properties of the table column, such as Name and DataType.
+
+
+
+
Fields
: A List of Field
+ objects.
+
+
+
+
+ Record: A list of data objects represents a single row in a Table.
+ Implements IEnumerable and the Data property which is used for DataBinding.
+
+
+
+
Records
: A List of
+ Record objects.
+
+
+
+
FieldValues
: A simple
+ Name/Value pair Dictionary. Use this class when adding and updating records.
+
+
+
+
FilterExpression
: Used
+ to filter records for query, update and delete.
+
+
+
+
FilterExpressionGroup
:
+ Used to create compound expressions by grouping FilterExpressions and
+ FilterExpressionGroups.
+
+
+
Database Fields
+
Fields (or Columns) can be of several common types:
+String, Int, UInt, Bool, Byte, Float, Double and DateTime, or can also be an array of any of
+these types.
+
Int Fields can be AutoIncrementing, and you can optionally
+specify one field to be Primary Key (it must be of type Int or String).
+
FileDb doesn't support the notion of NULL fields for the
+non-array type. Only array type fields can have NULL values. The non-array field
+values will always have a value, either zero or empty.
+
FileDb Records
+
FileDb supports two methods of data retrieval. You can say the
+"default" way is with the built-in Record and Records classes. Think of
+Record as the .NET DataRow class, and think of Table as a DataTable. Table
+is a list of Records, and a Record holds the actual values. You access Field
+values using indexing just as you would a DataRow, like this:
+
+
+
+
+
+ FileDb employeesDb = new FileDb();
+ employeesDb.Open( Employees.fdb" );
+
+ Table employees = employeesDb.SelectAllRecords();
+ Record record =
+ employees[0];
+ int id = (int) record["EmployeeId"];
+ // or
+ id
+ = (int) record[0];
+
+
+
+
+
To use a Table with LINQ, you do this:
+
+
+
+
+
+ var recs = from e in
+ employees
+ where (string)
+ e["FirstName"] == "John"
+ select e;
+
+
+
+
+
Notice we have to cast the record value to a string.
+ This is because, just like with the DataRow, Record
+ values are all type object.
+
Records and Custom Objects
+
Records are great because they require no additional
+ programming and they work with LINQ, albeit with some
+ casting. But you can use your own custom classes
+ if you want because FileDb has template (generic)
+ overloads for each of the SelectRecords methods.
+ You only need to create a class with public properties
+ which match the names of the fields you want to use.
+ Here's an example using the Employees table.
+
+
+
+
+
+ public class Employee
+ {
+ public int EmployeeID { get; set; }
+ public string LastName { get; set; }
+
+ public string
+ FirstName { get; set; }
+
+ public string Title {
+ get; set; }
+
+ public string
+ TitleOfCourtesy { get; set; }
+
+ public DateTime
+ BirthDate { get; set; }
+
+ public DateTime
+ HireDate { get; set; }
+
+ public string Address
+ { get; set; }
+
+ public string City {
+ get; set; }
+
+ public string Region {
+ get; set; }
+
+ public string
+ PostalCode { get; set; }
+
+ public string Country
+ { get; set; }
+
+ public string
+ HomePhone { get; set; }
+
+ public string
+ Extension { get; set; }
+
+ public Byte[] Photo {
+ get; set; }
+
+ public string Notes {
+ get; set; }
+
+ public int ReportsTo {
+ get; set; }
+ }
+
+
+
+
+
The templated SelectRecords versions return a IList<T>
+ where T is your custom type.
+
+
+
+
+
+
+ IList<Employee>
+ employees = employeesDb.SelectAllRecords<Employee>();
+ Employee employee
+ = employees[0];
+ int id = Employee.EmployeeId;
+
+ var emps = from e in
+ employees
+ where e.FirstName
+ == "John"
+ select e;
+
+
+
+
+
As you can see, this is much cleaner code. And
+ its actually more efficient since the Record class has
+ more overhead because its not as simple.
+
Searching and Filtering
+
FileDb uses FilterExpressions and
+ FilterExpressionGroups to filter records in queries and
+ updates. We use FilterExpressions for simple queries
+ which consist of a single field comparison (field =
+ 'value') and we use FilterExpressionGroups for compound
+ expressions, where multiple expressions and grouping are
+ required. You can add either FilterExpressions or
+ FilterExpressionGroups to a FilterExpressionGroup, thus
+ creating complex expresssions (FileDb processes
+ FilterExpressionGroups recursively).
+
You can either create your own manually in code or
+ use the built-in Expression Parser to create them for
+ you. The Expression Parser recognizes standard SQL
+ comparison operators. You can see it used in the
+ examples below. It also recognizes REGEX, which
+ uses Regular Expressions, and CONTAINS which uses
+ String.Contains. See the section on
+ Regular Expressions below for more info. Field names
+ prefixed with ~ specifies no-case comparison (for
+ strings only).
+
Each time you use () around an expression, a new
+FilterExpressionGroup will be created. The inner-most expressions are evaluated
+first, just as in SQL.
+
+
Example 1: Create a FilterExpression
+
+
+
+
+
+
+ // build an expression manually
+ FilterExpression searchExp = new FilterExpression( "LastName", "Peacock",
+ Equality.Equal );
+
+ // build the same expression using the
+ parser
+ searchExp = FilterExpression.Parse( "LastName = 'Peacock'" );
+ Table table = employeesDb.SelectRecords(
+ searchExp,
+ new string[] { "ID", "LastName" } );
+
+ // Or you can simply pass the string filter
+ directly - a FilterExpression will be
+ created in the same way as above
+
+ table = employeesDb.SelectRecords( "LastName
+ = 'Peacock'", new string[] { "ID", "LastName"
+ } );
+
+ foreach( Record record in table )
+ {
+ foreach( object value in record )
+ {
+
+ Debug.WriteLine( value );
+
+ }
+ }
+
+
+
+
+
+
+Example 2: Create a FilterExpressionGroup
+
+
This example creates two identical FilterExpressionGroups,
+one using the Expression Parser and the other with code.
+
+
+
+
+
// For string fields there are
+ 2 ways to specify no-case
+ comparisons: you can prefix fieldnames with ~ or you can use ~= as
+ demonstrated below
+ // The first form is needed when using the IN operator, eg.
+ FilterExpressionGroup filterExpGrp =
+ FilterExpressionGroup.Parse( "(FirstName ~= 'andrew' OR ~FirstName = 'nancy')
+ AND LastName = 'Fuller'" );
+ Table table = employeesDb.SelectRecords( filterExpGrp );
+
+ // equivalent building it manually
+ var fname1Exp = new FilterExpression( "FirstName", "andrew", Equality.Equal,
+ MatchType.IgnoreCase );
+ var fname2Exp = new FilterExpression( "FirstName", "nancy", Equality.Equal,
+ MatchType.IgnoreCase );
+ var lnameExp = new FilterExpression( "LastName", "Fuller", Equality.Equal );
+ // this constructor defaults to MatchType.UseCase
+ var fnamesGrp = new FilterExpressionGroup();
+ fnamesGrp.Add( BoolOp.Or, fname1Exp );
+ fnamesGrp.Add( BoolOp.Or, fname2Exp );
+ var allNamesGrp = new FilterExpressionGroup();
+ allNamesGrp.Add( BoolOp.And, lnameExp );
+ allNamesGrp.Add( BoolOp.And, fnamesGrp );
+
+ table = employeesDb.SelectRecords( allNamesGrp );
+
+ // or just pass the filter string directly
+
+ table = employeesDb.SelectRecords( "(FirstName ~= 'andrew' OR ~FirstName = 'nancy')
+ AND LastName = 'Fuller'" );
+
+
+
+
+
+
+FileDb supports these comparison operators:
+
+
+
+
+
+
+
=
+
+
+
+
Equality
+
+
+
+
~=
+
+
+
+
No-case equality - strings only
+
+
+
<>
+
+
+
+
Not Equal
+
+
+
!=
+
+
+
+
Not Equal (same as <>)
+
+
+
>=
+
+
+
+
Greater than or Equal
+
+
+
<=
+
+
+
+
Less than or Equal
+
+
+
+
+
REGEX
+
+
+
+
+
+
Use Regular Expression
+
+
+
+
CONTAINS
+
+
+
Use the .NET String's Contains method
+
+
+
+
+
IN
+
+
Creates a HashSet of values to use like SQL
+ IN operator
+
+
+
+
NOT
+
+
+
Logical Negation, e.g NOT CONTAINS
+
+
+
+
+
+
+
+
+
+
+
+
REGEX -
+Regular Expressions in searches and filtering
+
FileDb supports using Regular Expressions. You can use any RegEx supported by
+.NET. The Expression Parser supports MatchType.RegEx using the REGEX operator.
+Internally, FileDb uses FilterExpressions to evaluate fields. You don't
+need to use them because you can pass in filter strings and they'll be parsed
+into FilterExpressions/FilterExpressionGroups for you. This is just to
+show you how can create them manually if you want to. In
+the example below, both FilterExpressionGroups are identical.
+
+
+
+
+
+
// Using the Expression Parser
+
+ // You can use brackets around fieldnames if there are spaces in the
+ name
+ FilterExpressionGroup filterExpGrp = FilterExpressionGroup.Parse( "(~FirstName = 'steven' OR [FirstName]
+ REGEX 'NANCY') AND LastName = 'Fuller'" );
+ Table table = employeesDb.SelectRecords( filterExpGrp );
+
+ // we can manually build the same FilterExpressionGroup
+ var fname1Exp = FilterExpression.Parse( "~FirstName = steven" );
+ var fname2Exp = new FilterExpression( "FirstName", "NANCY", Equality.Regex );
+ var lnameExp = new FilterExpression( "LastName", "Fuller", Equality.Equal );
+ var fnamesGrp = new FilterExpressionGroup();
+ fnamesGrp.Add( BoolOp.Or, fname1Exp );
+ fnamesGrp.Add( BoolOp.Or, fname2Exp );
+ var allNamesGrp = new FilterExpressionGroup();
+ allNamesGrp.Add( BoolOp.And, lnameExp );
+ allNamesGrp.Add( BoolOp.And, fnamesGrp );
+
+ table = employeesDb.SelectRecords( allNamesGrp );
+
+
+
+
+
+
+
+
+
Using CONTAINS in searches and filtering
+
FileDb supports using Regular Expressions. You can use any RegEx supported by
+.NET. The Expression Parser supports MatchType.RegEx using the REGEX operator.
+Internally, FileDb uses FilterExpressions to evaluate fields. You don't
+need to use them because you can pass in filter strings and they'll be parsed
+into FilterExpressions/FilterExpressionGroups for you. This is just to
+show you how can create them manually if you want to. In
+the example below, both FilterExpressionGroups are identical.
+
+
+
+
+
+
// You can use brackets around fieldnames if there are spaces in the
+ name
+ FilterExpressionGroup filterExpGrp = FilterExpressionGroup.Parse( "(~FirstName = 'steven' OR [FirstName]
+ CONTAINS 'NANC') AND LastName = 'Fuller'" );
+ Table table = employeesDb.SelectRecords( filterExpGrp );
+
+ // we can manually build the same FilterExpressionGroup
+ var fname1Exp = FilterExpression.Parse( "~FirstName = steven" );
+ var fname2Exp = new FilterExpression( "FirstName", "NANCY", Equality.Contains );
+ var lnameExp = new FilterExpression( "LastName", "Fuller", Equality.Equal );
+ var fnamesGrp = new FilterExpressionGroup();
+ fnamesGrp.Add( BoolOp.Or, fname1Exp );
+ fnamesGrp.Add( BoolOp.Or, fname2Exp );
+ var allNamesGrp = new FilterExpressionGroup();
+ allNamesGrp.Add( BoolOp.And, lnameExp );
+ allNamesGrp.Add( BoolOp.And, fnamesGrp );
+
+ table = employeesDb.SelectRecords( allNamesGrp );
+
+
+
+
+
+
+
Sort Ordering
+
Query methods allow for sorting the results by fields. To
+get a reverse sort, prefix the sort field list with !. To get a no-case sort,
+prefix with ~. To get both reverse and no-case sort, use both ! and ~.
Another very powerful feature of FileDb is the ability to select a Table from
+another Table. This would allow you to be able to select data from a Table
+after the database file has been closed, for example.
+
Example:
+
+
+
+
+
+
+ customersDb.Open( path + "Customers.fdb" );
+
+// select all fields and records from the database table
+Table customers = customersDb.SelectAllRecords();
+
+Table subCusts = customers.SelectRecords( "CustomerID <> 'ALFKI'",
+new string[] { "CustomerID", "CompanyName", "City" }, new string[] { "~City", "~CompanyName"
+} );
+
+
+
+
+
Encryption
+
Using encryption with FileDb is simple. You only need to
+specify a string key when you open the database. After that everything is
+automatic. The only caveat is you must set a key before you add any records.
+Once a single record has been added without a key set you cannot later add
+records with a key. Its all or nothing. Likewise, you cannot add records with
+encryption and later add records without. You must set the encryption key
+each time you add any records.
+
Persisting Tables
+
You can easily save a Table as a new database using
+Table.SaveToDb. This method creates a new database file using the Fields
+in the Table then populates it using the Records in the Table. For
+example, you can select subsets of your data, save it as a new database and send
+it over the Internet.
You can also save a Table to a database from the
+ FileDb Explorer. Just right-click on the Grid to show
+ the context menu and select the "Create database from
+ Table..." menu item.
+
+
Using LINQ to Objects with FileDb
+
Microsoft has done an amazing job with LINQ.
+ They have invested a huge amount of time, effort and $
+ in this technology which allows you to query just about
+ any kind of data in a SQL-like way. We use LINQ
+ with FileDb to join Tables as we would using SQL.
+ The difference is that instead of doing it all in a
+ single step with SQL, we must do it in two steps.
+ First we select the data Tables from the database files
+ then we use LINQ to join them together.
+
LINQ to Objects produces a list of anonymous types as
+ its result set. This is good because we get
+ strongly typed data objects which we can easily use in WPF/Silverlight apps.
+
Here is an example of doing a simple select using
+ LINQ:
+
+
+
+
+
//
+ Using the IN operator. Notice the ~
+ prefix on the LastName field. This is how
+
+ // you can specify case insensitive searches
+
+ Table
+ employees = employeesDb.SelectRecords( "~LastName
+ IN ('Fuller', 'Peacock')" );
+
+ var query =
+ from record in employees
+ select new
+ {
+ ID = record["EmployeeId"],
+ Name = record["FirstName"] + " " + record["LastName"],
+ Title = record["Title"]
+ };
+
+ foreach( var rec in query )
+ {
+ Debug.WriteLine( rec.ToString() );
+ }
+
+
+
+
The only thing LINQ did for us in this example was
+ gave us a typed list of anonymous objects. Here's
+ the same thing but with custom objects:
+
+
+
+
IList<Employee> employees
+ = employeesDb.SelectRecords<Employee>(
+ "~LastName
+ IN ('Fuller', 'Peacock')" );
+
+ var query =
+ from e in employees
+ select e;
+
+ foreach( var emp in query )
+ {
+ Debug.WriteLine( emp.ToString() );
+ }
+
+
+
+
+
Now lets tap into LINQ's real power to join tables together
+like a SQL inner join. Notice in the following example we use the
+FilterExpression.CreateInExpressionFromTable
+method. We do this to get only the records we are going to need with LINQ.
+So using FileDb with LINQ is a two step process. You first select the
+records you will need then use them in the LINQ query. If your database
+files are large, you can filter the records like this. Otherwise you can
+just select all records.
+
+
+
+
+
FileDb customersDb = new FileDb(),
+ ordersDb = new FileDb(),
+ orderDetailsDb = new FileDb(),
+ productsDb = new FileDb();
+
+ customersDb.Open( "Customers.fdb" );
+ ordersDb.Open( "Orders.fdb" );
+ orderDetailsDb.Open( "OrderDetails.fdb" );
+ productsDb.Open( "Products.fdb" );
+
+ // get our target Customer records
+ // Note that we should select only fields we
+ need from each table, but to keep the code
+ // simple for this example we just pass in null for the field
+ list
+
+ FilterExpression filterExp =
+ FilterExpression.Parse( "CustomerID IN( 'ALFKI',
+ 'BONAP' )" );
+ FileDbNs.Table customers =
+ customersDb.SelectRecords( filterExp );
+
+ // now get only Order records for the target
+ Customer records
+ // CreateInExpressionFromTable will create
+ an IN FilterExpression, which uses a HashSet
+
+ // for high efficiency when filtering
+ records
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable(
+ "CustomerID", customers, "CustomerID" );
+ FileDbNs.Table orders =
+ ordersDb.SelectRecords( filterExp );
+
+ // now get only OrderDetails records for the
+ target Order records
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable(
+ "OrderID", orders, "OrderID" );
+ FileDbNs.Table orderDetails =
+ orderDetailsDb.SelectRecords( filterExp );
+
+ // now get only Product records for the
+ target OrderDetails records
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable(
+ "ProductID", orderDetails, "ProductID" );
+ FileDbNs.Table products =
+ productsDb.SelectRecords( filterExp );
+
+ // now we're ready to do the join
+
+ var query =
+ from custRec in customers
+ join orderRec in orders on custRec["CustomerID"]
+ equals orderRec["CustomerID"]
+ join orderDetailRec in orderDetails on
+ orderRec["OrderID"] equals
+ orderDetailRec["OrderID"]
+ join productRec in products on
+ orderDetailRec["ProductID"] equals
+ productRec["ProductID"]
+ select new
+ {
+ ID = custRec["CustomerID"],
+ CompanyName = custRec["CompanyName"],
+ OrderID = orderRec["OrderID"],
+ OrderDate = orderRec["OrderDate"],
+ ProductName = productRec["ProductName"],
+ UnitPrice = orderDetailRec["UnitPrice"],
+ Quantity = orderDetailRec["Quantity"]
+ };
+
+ foreach( var rec in query )
+ {
+ Debug.WriteLine( rec.ToString() );
+ }
+
+
+
+
Here's the same thing again using custom objects:
+
+
+
+
// get our target Customer records
+
+ FilterExpression filterExp =
+ FilterExpression.Parse( "CustomerID IN( 'ALFKI',
+ 'BONAP' )" );
+ IList<Customer> customers =
+ customersDb.SelectRecords<Customer>( filterExp );
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable<Customer>(
+ "CustomerID", customers, "CustomerID" );
+ IList<Order> orders =
+ ordersDb.SelectRecords<Order>( filterExp );
+
+ // now get only OrderDetails records for the
+ target Order records
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable<Order>(
+ "OrderID", orders, "OrderID" );
+ IList<OrderDetail> orderDetails =
+ orderDetailsDb.SelectRecords<OrderDetail>( filterExp );
+
+ // now get only Product records for the
+ target OrderDetails records
+
+ filterExp =
+ FilterExpression.CreateInExpressionFromTable<OrderDetail>(
+ "ProductID", orderDetails, "ProductID" );
+ IList<Product> products =
+ productsDb.SelectRecords<Product>(( filterExp );
+
+ // now we're ready to do the join
+
+ var query =
+ from custRec in customers
+ join orderRec in orders on custRec.CustomerID
+ equals orderRec.CustomerID
+ join orderDetailRec in orderDetails on
+ orderRec.OrderID equals orderDetailRec.OrderID
+ join productRec in products on
+ orderDetailRec.ProductID equals productRec.ProductID
+ select new
+ {
+ ID = custRec.CustomerID,
+ CompanyName = custRec.CompanyName,
+ OrderID = orderRec.OrderID,
+ OrderDate = orderRec.OrderDate,
+ ProductName = productRec.ProductName,
+ UnitPrice = orderDetailRec.UnitPrice,
+ Quantity = orderDetailRec.Quantity
+ };
+
+ foreach( var rec in query )
+ {
+ Debug.WriteLine( rec.ToString() );
+ }
+
+
+
+
+
+
+ Creating a Database
+
+
You create your database programmatically by defining
+Fields and adding them to an array then calling FileDb.Create, similar to below.
+Notice we set the ID field to be AutoIncrementing and PrimaryKey. This code
+creates a database with every type of field.
+
+
+
+
+
Field field;
+ var fieldLst = new List<Field>( 20 );
+ field = new Field( "ID", DataType.Int );
+ field.AutoIncStart = 0;
+ field.IsPrimaryKey = true;
+ fields.Add( field );
+ field = new Field( "FirstName", DataType.String );
+ fields.Add( field );
+ field = new Field( "LastName", DataType.String );
+ fields.Add( field );
+ field = new Field( "BirthDate", DataType.DateTime );
+ fields.Add( field );
+ field = new Field( "IsCitizen", DataType.Bool );
+ fields.Add( field );
+ field = new Field( "DoubleField", DataType.Double );
+ fields.Add( field );
+ field = new Field( "ByteField", DataType.Byte );
+ fields.Add( field );
+
+ // array types
+ field = new Field( "StringArrayField", DataType.String );
+ field.IsArray = true;
+ fields.Add( field );
+ field = new Field( "ByteArrayField", DataType.Byte );
+ field.IsArray = true;
+ fields.Add( field );
+ field = new Field( "IntArrayField", DataType.Int );
+ field.IsArray = true;
+ fields.Add( field );
+ field = new Field( "DoubleArrayField", DataType.Double );
+ field.IsArray = true;
+ fields.Add( field );
+ field = new Field( "DateTimeArrayField", DataType.DateTime );
+ field.IsArray = true;
+ fields.Add( field );
+ field = new Field( "BoolArray", DataType.Bool );
+ field.IsArray = true;
+ fields.Add( field );
+
+ var myDb = new FileDb();
+ myDb.Create( "MyDatabase.fdb", fieldLst.ToArray() );
+
+
+
+
+
+Adding Records
+
You add records to a database by creating a FieldValues
+object and adding field values. You do not need to represent every field of the
+database. Fields that are missing will be initialized to the default value (zero
+for numeric types, DateTime.MinValue,
+empty for String and NULL for array types).