WO2014145230A1 - Object-oriented data infrastructure - Google Patents

Object-oriented data infrastructure Download PDF

Info

Publication number
WO2014145230A1
WO2014145230A1 PCT/US2014/029954 US2014029954W WO2014145230A1 WO 2014145230 A1 WO2014145230 A1 WO 2014145230A1 US 2014029954 W US2014029954 W US 2014029954W WO 2014145230 A1 WO2014145230 A1 WO 2014145230A1
Authority
WO
WIPO (PCT)
Prior art keywords
record
field
data
oriented data
data infrastructure
Prior art date
Application number
PCT/US2014/029954
Other languages
French (fr)
Inventor
Mark Fiedler
Original Assignee
Recent Memory Incorporated
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Recent Memory Incorporated filed Critical Recent Memory Incorporated
Publication of WO2014145230A1 publication Critical patent/WO2014145230A1/en

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/28Databases characterised by their database models, e.g. relational or object models
    • G06F16/289Object oriented databases

Definitions

  • the application generally relates to an object-oriented data infrastructure for use in data conversion.
  • Data in modern computing systems generally takes the form of objects or structures comprising one or more elements of data, which can be of various types: e.g., numeric (both fixed- and floating-point, and of various bit widths), text (of various representational schemes, such as ASCII and Unicode), dates and times (again variously represented, with less standardization than numeric or text data), and "custom" data types defined by the particular system using the data type.
  • an internal object form represented in an object-oriented programming language (e.g., C++, Java, Python) and ephemerally stored in the random-access memory (RAM) of a computing device,
  • object-oriented programming language e.g., C++, Java, Python
  • RAM random-access memory
  • a single item of data (whether an object or a lone element) can assume any or all of these four states, passing between states by means of data conversions, which must take into account a number of things which generally differ between states. Not only does the internal representation of values (as an ordered set of binary digits or bits) generally vary between states for any given data type, but the overall structure of an object and the names applied to its elements will usually differ as well.
  • the internal object form of data is used for most operations (which are coded in one or more programming languages) and generally mediates between the other canonical states.
  • data entered by a user is converted to object form, from which it is converted to serialized form and transmitted across a network to a remote database module, which in turn deserializes it into an internal object form (possibly differing from the earlier one) before finally saving it in relational form in one or more tables of its database.
  • the database module converts data it retrieves from its database from relational to object form before serializing it for transmission to other modules.
  • Relational databases generally supply application programming interfaces (APIs) to accept SQL queries from a programming-language environment and return their results for processing in that environment.
  • APIs application programming interfaces
  • These APIs generally accept as input only fully-formed SQL statements or "prepared” SQL statements with tokens in place of the various data elements that correspond to the values of database columns, so the programmer must format the data elements manually, taking care to translate each element from its internal form into the appropriate text string representing it in the database table.
  • a data object representing a music track can be defined as class cTrack
  • Any user's workstation, with its internal memory, is like a workbench on which the user is working with specific items, connecting them (to name just one possible operation) in various specific ways.
  • a relational database by this analogy, is like a warehouse that contains not just the objects being worked on on any particular workbench, but the entire "universe” of objects that can be processed on any or all of those workbenches. It supplies the "raw material” for manipulation on the workstations/workbenches and stores the "finished items” in a retrievable form. It reflects not the actual short-term states of particular items, but the more permanent state of the potential universe from which those items may be constructed and in which they may be preserved. The need for organized storage and easy, flexible retrieval is reflected in the rich, powerful syntax of SQL.
  • object databases lack the relational structure that governs objects—especially those relations that tie objects being worked on to other objects that are not currently being worked on— and are also lacking in access to the broader universe of objects than can be worked on.
  • recordset/dataset objects deal in sets of tables, rows, columns and constraints (similar to those illustrated above) that do a poor job of reflecting the individual objects being worked on: Not only do they make it difficult to focus on an object stored in several tables (as in the above example), but they are useless in dealing with an object's potential properties and connections outside the database, or in dealing with objects that are not represented in a database.
  • the use of recordset/dataset objects in a program can conflict with direct SQL manipulation of the databases involved and can create unwanted duplicate copies of the objects involved.
  • a third kind of object-relational interface methodology is object-relational mapping (ORM)— as embodied, for example, in the free Java-language product Hibernate— which, in its various embodiments, generally combines the drawbacks of object databases with those of recordset/dataset objects.
  • ORM object-relational mapping
  • Object-relational mapping relies on some combination of (1) the active record pattern, in which a single row of a relational database table or view is "wrapped" into an object whose properties correspond to the columns of the table, with accessor methods to perform loading and saving operations, and/or (2) the data mapper pattern, which creates objects to map the properties of in-memory data objects to the columns of a relational database table or view (or, in the general case, some aspect of a persistent data store). Both of these patterns interpose a layer of code that automatically generates SQL code, effectively removing the SQL code from the programmer's direct control.
  • the present application provides an object-oriented data infrastructure that presents a different approach to the problems discussed above by preserving the virtues of both object-oriented and SQL programming.
  • the present application provides individual memory-resident record objects whose elements can be precisely and flexibly defined, using field objects, to produce the values required in any of the four canonical states.
  • the present application maps these record objects flexibly and precisely to their corresponding relational database tables (if any), automatically generating error-free SQL syntax that supports the free use of direct SQL queries with the APIs supplied with relational databases.
  • the present application also supports fields having a variable number of multiple values, which the active data pattern used in object-relational mapping does not support, and allows record objects to have properties unrelated to the database, to refer to other objects of classes unrelated to themselves, and to share these properties and references (along with any methods of their own) with any subclasses in the normal manner of objects.
  • the present application ensures that no more than a single instance of any record object in the database can exist in memory, while allowing unlimited access to that unique instance through a single object pointer.
  • the present application provides for complex record objects (with all of these attributes) which include any number of sets of references to other record objects without violating the uniqueness requirement.
  • the present application automates many of the functions of a data dictionary, particularly the transitions between the canonical states of data, and effectively propagates changes to the composition of data objects throughout a system, thereby enhancing both the reliability and the maintainability of the program code.
  • the present invention is directed to an object-oriented data infrastructure to convert data between different canonical states.
  • the object-oriented data infrastructure including a microprocessor, a memory in communication with the microprocessor and at least one record object residing in the memory and including a plurality of elements.
  • the at least one record object is defined by a record type.
  • the record type has a predetermined schema including at least one field object.
  • the at least one field object accesses and manipulates the plurality elements of the at least one record object and performs data conversions between the canonical states.
  • FIG. 1 schematically shows an embodiment of a computing system that can be used with the present application.
  • FIG. 2 shows an embodiment of the relationship between record objects and field objects in a memory.
  • FIG. 3 schematically shows the relationships between the different canonical states of data.
  • FIG. 1 schematically shows a computing system 100 that can be used with the present application.
  • the computing system or computer 100 can include one or more processors or microprocessors 104, one or more memory devices 106 and one or more databases 108 in communication with each other.
  • the computing system 100 can also include a communication system, such as a modem, 110 to permit the computing system 100 to communicate with other computing systems over the Internet or by any other suitable communication technique or method.
  • the computing system 100 can include a user interface 114, such as a monitor, display, input device and/or other associated equipment or software, to enable a user or operator to receive information from and interact with the computing system 100. Records and Fields
  • FIG. 2 shows an embodiment of the relationship between record objects and field objects. A description of record objects and field objects is provided below.
  • the present application includes a class hierarchy of record objects that represents a system's data objects in all of their canonical states, and a class hierarchy of field objects used to access and manipulate the elements of record objects and to perform the conversions between canonical states.
  • object classes can be declared and defined in code files shared by a plurality of modules in a particular system.
  • All record objects can be directly or indirectly derived from a single base class, cRecord.
  • the data elements of a record may be of any primitive, system-defined or "custom" type, and may be single-valued (i.e., scalar) or multiple-valued (i.e., arrays or vectors).
  • the record hierarchy is: cRecord
  • Objects of cDBComplexRecord and its subclasses include references to other cRecord-derived objects, as discussed below. Its subclass cPlaylistRecord incorporates a list of objects of the class cTrackRecord. In general, subclasses of cRecord can have data members and methods dealing with data and objects as may be determined by any particular implementation context.
  • the field classes form the following hierarchy: cField
  • cDurationField clntTagField encapsulates integer-valued tags that refer to entities defined outside the scope of the field and record apparatus; its subclass cGenreTagField can refer to system- defined genre objects.
  • a data element in a cRecord object of any cField type may be single-valued (scalar) or multiple-valued (array- valued).
  • Each record of whatever type, has a contents array that contains (1) the values of its scalar numeric-valued and other fixed-width fields and (2) pointers to strings and arrays (respectively) holding the values of its string-valued, array-valued and other variable-width fields.
  • Each particular field object belonging to the record type has:
  • a virtual size function that returns the size (in bytes) of the corresponding element in a record's contents array, i.e., the size of the internal representation of the field's data element (if of fixed length) or of a pointer to its internal
  • a record type object corresponding to each record type, has an field array of pointers to the field objects (each of the appropriate data type) that correspond to a record's elements.
  • This array and thereby the succession of fields in the record structure, can be built by successively calling the function cRecord::addField() for each data element in order, which function appends to the record type's field array a pointer to a field object of the appropriate class.
  • the offsets of successive elements may be determined by adding their respective field sizes.
  • a prototype of a cTrackRecord equivalent to the music track object illustrated above can be constructed as follows: clntField* pf r_GlobalID; // cf. pfTr_TrackID
  • constructors used here for the various cField subclasses are of the form cField( cRecord* pRec, QString sName4 Schema, QString sName4Display,
  • sName4Schema the name of the field for the purpose of a record schema for this record type.
  • a schema for a particular version of the record can be assembled by creating a sequential list of these names for the fields of a record, and this sequence may be compared to the corresponding sequences for other versions.
  • nDisplayWidth the default width, in pixels, for displaying the field (as in a grid).
  • field classes have the following virtual functions, defined at appropriate levels of the field class hierarchy:
  • virtual void cField : write ( cRecord* pRec, cIO* pIO ) ;
  • variable-length value such as a string can be terminated, if feasible, with a null character, or preceded by an integer value representing the length of the data value.
  • the values of a multiple-valued field can be preceded by an integer value representing the number of values.
  • Values can also be serialized in various self- describing forms, incorporating their string-valued field names (as in various forms of extensible markup language (XML); the sName4Schema property mentioned above can be used for this purpose.
  • a display function or functions each taking a record pointer and an optional index as arguments, that return string, tabular or graphic values (or references thereto) containing a form of a data element that can be displayed to a human user.
  • nlndex is the (0-based) index of the desired value for a multiple-valued field; the default value of -1 applies only to a scalar field.
  • object classes derived from cRecord and cField are "normal" object classes that can have data members and methods independent of the apparatus described here.
  • the cRecord class has write and read functions, similar to those of the cField class, for serializing the set of data element values of any object directly or indirectly derived from cRecord, each taking as an argument a pointer to an object representing a file, stream or similar means of serialization: void cRecord : : read ( cIO* pIO ) ;
  • Reading is performed by calling the read function of each constituent field in order (e.g., in the order in which the fields were added to the prototype record), and writing is performed by calling the write function of the each constituent field in the same order.
  • a self-describing syntax such as XML
  • the sequence of field values can be enclosed in a record value, using a unique string-valued name to represent the record type.
  • the present application provides flexible automated support for objects directly or indirectly derived from cRecord to be stored in and retrieved from relational databases.
  • the present application automates the inclusion in SQL statements (coded by applications programmers) of the table and column names and the data values that correspond to a record object's fields.
  • the present application also automates the conversion of the results of such queries into updated data values in the record objects involved.
  • a particular relational database can store the scalar fields of a particular record class either in a single table or in multiple tables. In either case, the scalar fields of a single record are stored in a single row in each table. The relationship, if any, of the primary keys for these various rows is a matter of database design.
  • a form of SQL statement to insert a new row into a relational database is:
  • a form of SQL statement to retrieve a row or a set of records from a relational database is:
  • JOINs can be concatenated to involve three or more tables; the aliasn expressions shown here identify the particular table from which each column is taken.
  • the present application enables all of the above kinds of SQL statements to be coded directly by applications programmers, with the enumerated column names and values accurately and reliably supplied by the following automated means.
  • a field map can be constructed to map a scalar field of a record to the name of the corresponding column of a relational database table: cDBFieldMap : : cDBFieldMap ( cField* pField, QString sDBFieldName, bool bSuppressKey ) ;
  • bSuppressKey is true if (and only if) the field is a primary-key field, which is suppressed in INSERT statements.
  • a multiple field map is used to store and retrieve the contents of a multiple- valued field in a "many-to-many" target table having columns for (1) a target field holding the data value, (2) an ID field holding the integer primary key value of the record in the source table that holds the scalar fields of the record, and optionally (3) a sequence field, the (zero-based) integer index of the value.
  • Its constructor declaration follows: cDBMultipleFieldMap : : cDBMultipleFieldMap ( cField* pField,
  • cDBMultipleFieldMap is implemented as a subclass of cDBFieldMap.
  • a multiple field map can specify an SQL ORDER BY specification to determine the order of the values (array indices) in the loaded record.
  • the mapping of a record type to a relational database generally requires a table map for each database table storing the record's scalar fields and a multiple field map for each multiple-valued field. These can be registered in a database record type object (class cDBRecordType) that can be mapped to, or otherwise associated with, the corresponding record type (cRecordType) object.
  • a multiple field map can be constructed and added to a database record type object using: cDBMultipleFieldMap* cDBRecordType : : addMultipleField ( cField* pField,
  • the following code can be used to build a database record type object to prepare for the storage and retrieval of a music track record (class cTrackRecord) in a relational database, using a single table for the scalar fields: void buildTrack ( )
  • cDBRecordType* pType cDBRecordType :: get ( TRACK_RECORD );
  • pfmGlobalTrackID pTMap->addField ( pfTr_GlobalID, "track_id", true ) ;
  • the following code can be used to build a database record type object to prepare for the storage and retrieval of an artist record (class cArtistRecord) in a relational database, using multiple tables for the scalar fields: void buildArtist ( )
  • pTMap pType->addTable ( "people_roles " , "pr” );
  • subclasses of cField can have virtual functions, defined at appropriate levels of the cField class hierarchy, to format the values of their data elements from internal object form into the string form used in SQL statements for a particular database, and to parse the column values from the results of SQL queries (generally supplied as strings) into the field object's internal object form: virtual QString cField : : sqlFormat ( cDB* pDB, cRecord* pRec,
  • sqlFormat() and sqlParse() Two notes on sqlFormat() and sqlParse(): (1) Similar functions can be provided to perform any conversions required to use the parameterized or "prepared” SQL statements provided by some APIs. (2) Although these functions are generally declared in the header files common to all modules using this data infrastructure, these functions can be implemented as empty “stubs" in modules that do not use a relational database.
  • QString cDBTableMap : listlnsertValues ( cDB* pDB, cRecord *pRec ); returns a comma-separated list of field values, using the fields' sqlFormat() functions and omitting any primary-key column;
  • cDBRecordType parseRow ( cDBQuery* pQuery, cRecord* pRec ) ;
  • cDBTableMap For each table to return comma-separated lists of their column names and values, as applicable, in the order in which the corresponding table maps were added to the database record type object.
  • cDBRecordType ::parseRow() calls cDBTableMap ::parseRow() for each table (making the only actual use of the index argument) to update all of the scalar fields of the record.
  • bool cField : sqlWriteMultiple ( cDB* pDB, cRecord *pRec,
  • int i!DFieldValue updates the applicable rows of a multiple-valued field's target table (as identified in its multiple field map) to reflect the field's values. It does so by first deleting all of the target table's rows for the given record by execuring an SQL statement of the form
  • int ilDFieldValue updates a multiple-valued field in the given record pRec to reflect all of the field's current values for pRec in the field's target table. It does so by first clearing the field's values, then retrieving all of the target table's rows for the given record by executing an SQL statement of the form
  • sqlWriteMultiple() and sqlReadMultiple() can be defined as empty "stubs" in modules that do not use a relational database.
  • All of the multiple-value fields of a record can be saved to a database by calling the function bool cDBRecordType : : saveMultipleFields ( cDB* pDB, cRecord* pRec
  • all of the multiple-value fields of a record can be updated from a database by calling the function bool cDBRecordType : : loadMultipleFields ( cDB* pDB, cRecord* pRec which calls sqlWriteMultipleQ using the field pointer of each of its multiple table maps.
  • cDBTableMap* pTMap pTrackType->getTableMap ( sTableName ); QString sQuery;
  • cDBQuery* pQ gDB->query( sQuery, true ) ;
  • iGlobalTrackID pTRec->get ( pfTr_GlobalID );
  • cDBTableMap* pTMap pTrackType->getTableMap ( sTableName ); QString sQuery;
  • iTrackID pTRec->get ( pfTr_GlobalID );
  • the canonical set of operations known as CRUD— create, read, update, delete— can be similarly automated for cRecord-derived objects stored in a relational database if the cDBRecordType object can identify an integer primary-key field for each such record type, whose value uniquely identifies each record of that type. Such a primary-key field can often be chosen from among the columns of one or more database tables corresponding to a record type.
  • a primary key can be provided as a local database field (class cLocalDBField, derived from cField), which is carried internally in cRecord-derived objects in a single application module and is used as a primary key in a local database attached to that module, but not serialized for transmission to other modules.
  • Local database fields have other uses, e.g., to indicate a record status that has significance only for a single module.
  • a record of a type without a primary-key field can often be uniquely identified by combining the values of a set of fields termed compound-key fields.
  • Every cField-derived class can identify a string-valued data type that may be used in SQL, e.g., "INTEGER” or "TEXT”.
  • the cDBRecordType object can carry a table name.
  • the cDBRecordtype object can identify any foreign-key constraints (discussed below under "Complex Record Objects") using pointers to the cField objects involved.
  • the cDBRecordType object carries a list of any local database fields, which is used in storing and retrieving database records.
  • a cDBRecordType object can be created for each stored record type, storing its scalar data elements in a single table represented by a table map that carries a field map for each scalar field, using the corresponding cField object's sName4Schema property as the corresponding column name.
  • a cDBMultipleFieldMap can be created for each muliple-valued field, giving system-generated names to the target table and its three columns:
  • the target name can combine the name of the source table and the field's sName4Schema property
  • the ID field column can be assigned the name of the cDBRecordType 's primary-key field
  • the column containing the data value can be assigned the field's sName4Schema property
  • the sequence field column can be assigned the name "SEQUENCE”.
  • a complete set of tables can be created using SQL CREATE TABLE statements prepared from each cDBRecordType, specifying:
  • a track record can appear not only in the set of all track records (or any selected subset thereof), but also in multiple playlists.
  • model-view architecture used in computing applications that display data to a human user— in which a plurality of views of data collections (e.g., various lists or grids displaying data objects) can display data from a single internal model giving access to a collection of data objects— each of these distinct collections of track records would correspond to a different model.
  • data collections e.g., various lists or grids displaying data objects
  • Each of these models can be associated with an ordered collection of pointers to objects of a single cRecord subclass (with additional properties, described below) termed a dataset (class cDataset; not to be confused with the recordset/dataset objects referred to in the prior art).
  • a dataset class cDataset; not to be confused with the recordset/dataset objects referred to in the prior art.
  • Each distinct record can be represented in internal memory by a single cRecord object, represented by a single cRecord* pointer in any number of datasets, ensuring that changes to the record's data elements will be reflected in all such datasets. Even with this benefit, there are two significant challenges:
  • a datastore class (cDatastore) is given control over the CRUD operations, with virtual functions for loading, updating, inserting and removing records.
  • cDatastore has a relational datastore subclass (cDBDatastore) that works with a relational database and implements the CRUD functions as detailed above, using the field-map/table-map/database-record-type apparatus. Any dataset can be associated with a datastore, relational or not.
  • cDBDatastore relational datastore subclass
  • Each object of the cDBDatastore class maintains a relational datastore index (class cDBIndex) for each record type, mapping a (unique) pointer to each record held in memory to the record's primary-key value. All CRUD operations update this index as appropriate.
  • the relational datastore index is checked to see whether a record already resides in memory; if so, the resident record is used rather than being (re-)loaded from the database.
  • the record object class representing playlists in this example system is a subclass of the complex record object class, cDBComplexRecord, which covers record objects with at least one (multiple-valued) data element that represents an ordered collection of other cRecord-derived objects termed component records. Each such collection in a complex record object is represented by
  • a foreign-key constraint is established for each component field with a primary-key column in a table where the component records are stored.
  • Component datasets can be associated with models as described above to display their record data.
  • Functions are provided for linking component fields with component datasets, void cDBComplexRecord : : addDataset ( cDataset*& pDS, cField *pField ) ; accessing component datasets given a component field pointer, cDataset* cDBComplexRecord :: getDataset ( cField* pField ) ; and loading component datasets from the datastore, void cDBDatastore : : loadFieldBasedDataset ( cDBComplexRecord* pDBCRec,
  • Subclasses of cDBComplexRecord are implemented so that loading a complex record from a datastore automatically loads all of its component fields, and saving a complex record to its datastore automatically saves all of its component fields.
  • cBlobField which handles references to images and/or other binary large objects (BLOBs).
  • BLOBs binary large objects
  • Each distinct BLOB can be identified by a unique integer ID number of system-wide scope, and the contents of a cBlobField is one or more such BLOB ID values (an ID value of 0, if not assigned to any actual BLOB, can serve as a null value).
  • BLOBs can be stored:
  • an integer BLOB ID value in a cRecord object can be used to retrieve the corresponding BLOB from the BLOB map; or, if not in the BLOB map, to load the BLOB into the BLOB map from the BLOBs table.
  • the BLOB map and the BLOBS table can incorporate additional fields such as the dates and times of a BLOB's creation and most recent revision, which can be of use in updating BLOB values.
  • a cBlobField value can be serialized as follows:
  • FIG. 3 schematically shows an embodiment of the relationships between the different canonical states of data and how the different states of data may be communicated between components.
  • pure data values (which should have no functionality other than the infrastructure's own data-handling methods) can be separated from object functionality.
  • Subclassing of field and record objects can be provided for functionality independent of data contents or values.
  • tTimeSpan is a "custom" data type defined for this particular system: typedef unsigned long tTimeSpan;
  • Embodiments within the scope of the present application include program products having machine-readable media for carrying or having machine-executable instructions or data structures stored thereon.
  • Machine-readable media can be any available non-transitory media that can be accessed by a general purpose or special purpose computer or other machine with a processor.
  • machine- readable media can comprise RAM, ROM, EPROM, EEPROM, CD-ROM or other optical disk storage, magnetic disk storage or other magnetic storage devices, or any other medium which can be used to carry or store desired program code in the form of machine-executable instructions or data structures and which can be accessed by a general purpose or special purpose computer or other machine with a processor.
  • Machine-executable instructions comprise, for example, instructions and data which cause a general purpose computer, special purpose computer, or special purpose processing machines to perform a certain function or group of functions.

Landscapes

  • Engineering & Computer Science (AREA)
  • Databases & Information Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Data Mining & Analysis (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

An object-oriented data infrastructure automates data conversions between object, relational, serialized and displayed states while enabling both object-oriented and SQL programming in the same body of code. The infrastructure provides individual memory-resident record objects whose elements can be precisely and flexibly defined, using field objects, to produce the values required in any of the four canonical states. In one embodiment, the infrastructure maps these record objects flexibly and precisely to their corresponding relational database tables (if any), automatically generating error-free SQL syntax that supports the free use of direct SQL queries with the APIs supplied with relational databases.

Description

OBJECT-ORIENTED DATA INFRASTRUCTURE
CROSS-REFERENCE TO RELATED APPLICATION
[0001] This application claims the benefit of U.S. Provisional Application No. 61/790,499, filed March 15, 2013, entitled OBJECT-ORIENTED DATA INFRASTRUCTURE, which Application is incorporated by reference herein in its entirety.
BACKGROUND
[0002] The application generally relates to an object-oriented data infrastructure for use in data conversion.
[0003] Data in modern computing systems generally takes the form of objects or structures comprising one or more elements of data, which can be of various types: e.g., numeric (both fixed- and floating-point, and of various bit widths), text (of various representational schemes, such as ASCII and Unicode), dates and times (again variously represented, with less standardization than numeric or text data), and "custom" data types defined by the particular system using the data type.
[0004] Modern computing systems carry data in four canonical forms or states:
(1) an internal object form, represented in an object-oriented programming language (e.g., C++, Java, Python) and ephemerally stored in the random-access memory (RAM) of a computing device,
(2) a relational form, typically represented in Structured Query Language (SQL) and persistently stored in the tables of a relational database on a peripheral or remote storage device,
(3) in serialized form, as in messages transmitted (as streams or datagrams) between system modules, over a network, or as data stored in "flat" files in memory or on a peripheral device, and
(4) as displayed to a human user, in various text, tabular and graphic forms. [0005] A single item of data (whether an object or a lone element) can assume any or all of these four states, passing between states by means of data conversions, which must take into account a number of things which generally differ between states. Not only does the internal representation of values (as an ordered set of binary digits or bits) generally vary between states for any given data type, but the overall structure of an object and the names applied to its elements will usually differ as well.
[0006] The creation and maintenance of a data dictionary to specify and standardize how data is represented in its various states, to keep track of the various corresponding names of data objects and elements in their various states, and to coordinate data conversions between states, is a fundamental task of system design and maintenance. Implementing the conversions— which are numerous, occurring throughout the program code— is one of the most tedious, time-consuming and error-prone aspects of programming. The difficulty is not limited to a system's initial implementation: when the composition of a data structure changes, all of the affected conversions must be found and changed accordingly. Programmers must conscientiously attend to all of these conversions, advantageously with guidance from the data dictionary and often with some help from the programming environment (which must be learned) or from the system (which must be implemented).
[0007] In practice, the internal object form of data is used for most operations (which are coded in one or more programming languages) and generally mediates between the other canonical states. In a common example, data entered by a user is converted to object form, from which it is converted to serialized form and transmitted across a network to a remote database module, which in turn deserializes it into an internal object form (possibly differing from the earlier one) before finally saving it in relational form in one or more tables of its database. Conversely, the database module converts data it retrieves from its database from relational to object form before serializing it for transmission to other modules.
[0008] The conversions between the internal object and relational states of data, are especially tedious and time-consuming to implement and maintain, and are an order of magnitude more error-prone. They come under the general heading of the object- relational interface, which has long been an area of concern (both theoretical and practical) for system designers and programmers. The following discussion provides a small illustration of the difficulty associated with the object-relational interface.
[0009] Relational databases generally supply application programming interfaces (APIs) to accept SQL queries from a programming-language environment and return their results for processing in that environment. These APIs generally accept as input only fully-formed SQL statements or "prepared" SQL statements with tokens in place of the various data elements that correspond to the values of database columns, so the programmer must format the data elements manually, taking care to translate each element from its internal form into the appropriate text string representing it in the database table.
[0010] For example, in a system in which recording artists can compile collections of their own music tracks and later register them in a global database from which playlists of music tracks may be assembled, a data object representing a music track can be defined as class cTrack
{
Int m_nGlobalID;
int m_nArtistID;
int m_nTrackID; // for this artist: compare m_nGlobalID QString m_sArtistName;
int m_nFormat; // standing for, e.g., MP3 or Ogg Vorbis QString m_sComposer;
QVector< int > m_anGenres ; // array of ID3V1 genre tags tTimeSpan m_tDuration;
QString m_sTitle;
QString m_sLanguage;
QString m_sLead_performer; and can be saved to the database by generating an SQL UPDATE statement using the following code:
QString trackUpdateString ( cTrack* pTrack )
{
QString sUpdate; QTextStream ( &sUpdate ) « "UPDATE tracks ( global_id,
artist_id, "
<< " artist_name, track_id, composer_name, duration_msec, << " track_title, track_language, lead_performer_name ) values ("
« pTrack->m_nTrackID « "," « pTrack->m_nArtistID « "," << pTrack->m_sArtistName << "," << pTrack->m_sComposer <<
« pTrack->m_tDuration « "," « pTrack->m_sTitle « "," << pTrack->m_sLanguage << "," << pTrack->m_sLead_performer « " ) " ; and passing the string that this function returns to a database-specific API to perform the update. Care would need to be taken to include all of the data elements and their values in the same order (a task that would be even more challenging without using the QTextStream object illustrated here). Not shown in this code are any function calls that might be needed to convert the various data element values for inclusion in the database, or the escape-string processing needed to deal with single quote marks (and the like) in text elements.
[0011] The array- valued genre field would need to be saved in a separate "many-to- many" table, which would involve a number of steps not shown here, but with similar difficulties. Both sets of operations would be required to save a single cTrack object.
[0012] The reverse operation, retrieving a music track record from the database (without its genre information), can be performed with a SQL SELECT statement:
QString trackSelectString ( )
{
QString sUpdate;
QTextStream ( &sUpdate ) « "SELECT global_id, artist_id, "
<< "artist_name, track_id, composer_name, duration_msec, " << track_title, "track_language, lead_performer_name " << "from tracks";
[0013] Passing the returned string to the appropriate API produces a result structure that will need to be parsed into a cTrack object. This parsing is accomplished by calling a database-specific parsing function repeatedly, once for each data element in the SELECT statement, in the exact order of the SELECT statement. Each call of the parsing function typically returns a text string that must be converted into the appropriate (numeric or other) form before assigning it to the corresponding element of cTrack. Only text elements may not need to be converted. An additional set of operations involving the "many-to-many" tables, similar to those required for saving the record, would be needed to retrieve the array of genre tags.
[0014] The considerable effort required to implement and maintain an object- relational interface— a small part of which is illustrated in this example— has given rise, over the past few decades, to two broad classes of methodologies designed to mitigate the effort: object databases and recordset/dataset objects. The former export the various objects stored in internal memory into persistent storage and retrieve them when needed, as in a subsequent session; the latter import the relational structure of database tables, with their rows, columns, constraints and relations, into internal memory.
[0015] To understand the drawbacks of these methodologies, it is worth considering the general purpose and mode of use of computing systems by way of an analogy. Any user's workstation, with its internal memory, is like a workbench on which the user is working with specific items, connecting them (to name just one possible operation) in various specific ways. A relational database, by this analogy, is like a warehouse that contains not just the objects being worked on on any particular workbench, but the entire "universe" of objects that can be processed on any or all of those workbenches. It supplies the "raw material" for manipulation on the workstations/workbenches and stores the "finished items" in a retrievable form. It reflects not the actual short-term states of particular items, but the more permanent state of the potential universe from which those items may be constructed and in which they may be preserved. The need for organized storage and easy, flexible retrieval is reflected in the rich, powerful syntax of SQL.
[0016] Seen in this light, object databases lack the relational structure that governs objects— especially those relations that tie objects being worked on to other objects that are not currently being worked on— and are also lacking in access to the broader universe of objects than can be worked on. Conversely, recordset/dataset objects deal in sets of tables, rows, columns and constraints (similar to those illustrated above) that do a poor job of reflecting the individual objects being worked on: Not only do they make it difficult to focus on an object stored in several tables (as in the above example), but they are useless in dealing with an object's potential properties and connections outside the database, or in dealing with objects that are not represented in a database. Moreover, the use of recordset/dataset objects in a program can conflict with direct SQL manipulation of the databases involved and can create unwanted duplicate copies of the objects involved.
[0017] A third kind of object-relational interface methodology is object-relational mapping (ORM)— as embodied, for example, in the free Java-language product Hibernate— which, in its various embodiments, generally combines the drawbacks of object databases with those of recordset/dataset objects.
[0018] Object-relational mapping relies on some combination of (1) the active record pattern, in which a single row of a relational database table or view is "wrapped" into an object whose properties correspond to the columns of the table, with accessor methods to perform loading and saving operations, and/or (2) the data mapper pattern, which creates objects to map the properties of in-memory data objects to the columns of a relational database table or view (or, in the general case, some aspect of a persistent data store). Both of these patterns interpose a layer of code that automatically generates SQL code, effectively removing the SQL code from the programmer's direct control.
[0019] Therefore what is needed is an objected-oriented data infrastructure that can easily and efficiently convert data between the different canonical states, and especially between the internal object form and the relational form.
SUMMARY
[0020] The present application provides an object-oriented data infrastructure that presents a different approach to the problems discussed above by preserving the virtues of both object-oriented and SQL programming. The present application provides individual memory-resident record objects whose elements can be precisely and flexibly defined, using field objects, to produce the values required in any of the four canonical states. The present application maps these record objects flexibly and precisely to their corresponding relational database tables (if any), automatically generating error-free SQL syntax that supports the free use of direct SQL queries with the APIs supplied with relational databases. The present application also supports fields having a variable number of multiple values, which the active data pattern used in object-relational mapping does not support, and allows record objects to have properties unrelated to the database, to refer to other objects of classes unrelated to themselves, and to share these properties and references (along with any methods of their own) with any subclasses in the normal manner of objects. The present application ensures that no more than a single instance of any record object in the database can exist in memory, while allowing unlimited access to that unique instance through a single object pointer. The present application provides for complex record objects (with all of these attributes) which include any number of sets of references to other record objects without violating the uniqueness requirement.
[0021] Going beyond the object-relational interface, the present application automates many of the functions of a data dictionary, particularly the transitions between the canonical states of data, and effectively propagates changes to the composition of data objects throughout a system, thereby enhancing both the reliability and the maintainability of the program code.
[0022] The present invention is directed to an object-oriented data infrastructure to convert data between different canonical states. The object-oriented data infrastructure including a microprocessor, a memory in communication with the microprocessor and at least one record object residing in the memory and including a plurality of elements. The at least one record object is defined by a record type. The record type has a predetermined schema including at least one field object. The at least one field object accesses and manipulates the plurality elements of the at least one record object and performs data conversions between the canonical states.
[0023] One advantage of the present application over record set/dataset objects and object-relational mapping is the automatic generation of error- free SQL syntax that supports the free use of direct SQL queries with the APIs supplied with the relational databases.
[0024] Other features and advantages of the present application will be apparent from the following, more detailed description of the embodiments, taken in conjunction with the accompanying drawings which illustrate, by way of example, the principles of the application.
BRIEF DESCRIPTION OF THE DRAWINGS
[0025] FIG. 1 schematically shows an embodiment of a computing system that can be used with the present application.
[0026] FIG. 2 shows an embodiment of the relationship between record objects and field objects in a memory.
[0027] FIG. 3 schematically shows the relationships between the different canonical states of data.
[0028] Wherever possible, the same reference numbers will be used throughout the drawings to refer to the same or like parts.
DETAILED DESCRIPTION OF THE EMBODIMENTS
[0029] FIG. 1 schematically shows a computing system 100 that can be used with the present application. The computing system or computer 100 can include one or more processors or microprocessors 104, one or more memory devices 106 and one or more databases 108 in communication with each other. The computing system 100 can also include a communication system, such as a modem, 110 to permit the computing system 100 to communicate with other computing systems over the Internet or by any other suitable communication technique or method. The computing system 100 can include a user interface 114, such as a monitor, display, input device and/or other associated equipment or software, to enable a user or operator to receive information from and interact with the computing system 100. Records and Fields
[0030] FIG. 2 shows an embodiment of the relationship between record objects and field objects. A description of record objects and field objects is provided below.
[0031] The present application includes a class hierarchy of record objects that represents a system's data objects in all of their canonical states, and a class hierarchy of field objects used to access and manipulate the elements of record objects and to perform the conversions between canonical states. These object classes can be declared and defined in code files shared by a plurality of modules in a particular system.
[0032] All record objects can be directly or indirectly derived from a single base class, cRecord. The data elements of a record may be of any primitive, system-defined or "custom" type, and may be single-valued (i.e., scalar) or multiple-valued (i.e., arrays or vectors). In the example illustrated here, the record hierarchy is: cRecord
c rackRecord
cArtistRecord
cDBComplexRecord
cPlaylistRecord
[0033] Objects of cDBComplexRecord and its subclasses include references to other cRecord-derived objects, as discussed below. Its subclass cPlaylistRecord incorporates a list of objects of the class cTrackRecord. In general, subclasses of cRecord can have data members and methods dealing with data and objects as may be determined by any particular implementation context.
[0034] Each type of data element that occurs in a record object— whether numeric, string, system-defined or "custom"— has a corresponding field class, directly or indirectly derived from the base class cField. In the example illustrated here, the field classes form the following hierarchy: cField
clntField
clntTagField
cGenreTagField
cInt64Field cTextField
cTimeField
cDurationField clntTagField encapsulates integer-valued tags that refer to entities defined outside the scope of the field and record apparatus; its subclass cGenreTagField can refer to system- defined genre objects.
[0035] A data element in a cRecord object of any cField type may be single-valued (scalar) or multiple-valued (array- valued).
[0036] Each record, of whatever type, has a contents array that contains (1) the values of its scalar numeric-valued and other fixed-width fields and (2) pointers to strings and arrays (respectively) holding the values of its string-valued, array-valued and other variable-width fields. Each particular field object belonging to the record type has:
(1) a virtual size function that returns the size (in bytes) of the corresponding element in a record's contents array, i.e., the size of the internal representation of the field's data element (if of fixed length) or of a pointer to its internal
representation (if of variable length, as a string or array),
(2) an integer offset value that specifies the position in the contents array of the
field's value or of a pointer to the field's value;
(3) a pointer or other reference to the record type object, which can be checked
against its use in a record's get and put functions;
[0037] Using each successive field's size function, these values and pointers can be "packed" contiguously in the contents array.
[0038] A record type object, corresponding to each record type, has an field array of pointers to the field objects (each of the appropriate data type) that correspond to a record's elements. This array, and thereby the succession of fields in the record structure, can be built by successively calling the function cRecord::addField() for each data element in order, which function appends to the record type's field array a pointer to a field object of the appropriate class. By assigning 0 as the offset of the first element, the offsets of successive elements may be determined by adding their respective field sizes. A prototype of a cTrackRecord equivalent to the music track object illustrated above can be constructed as follows: clntField* pf r_GlobalID; // cf. pfTr_TrackID
clntField* pfTr_ArtistID;
cTextField* pfTr_ArtistName;
clntField* pf r_TrackID; // for this artist only: cf. pfTr_GlobalID
cFormatTagField* pf r_Format; // standing for, e.g., MP3 or Ogg Vorbis
cTextField* pfTr_composer;
cGenreTagField* pfTr_genre;
cDurationField* pf r_duration;
cTextField* pfTr_title;
cTextField* pfTr_language;
cTextField* pfTr_lead_performer;
void cTrackRecord :: init ( )
{
addField( pfTr_GlobalID = new clntField (
this, "global_id", "Global ID", 40 ) );
addField( pfTr_ArtistID = new clntField (
this, "artist_id", "Artist ID", 40 ) );
addField( pfTr_ArtistName = new cTextField (
this, "artist_name", "Artist Name", 100 ) );
addField( pfTr_TrackID = new clntField (
this, "track_id", "Track ID", 50 ) );
addField( pfTr_Format = new cFormatTagField (
this, "format", "Format", 50 ) );
addField( pfTr_composer = new cTextField (
this, "composer", "Composer", 100 ) ) ;
addField( pfTr_genre = new cGenreTagField (
this, "genre", "Genre (s)", 100, true ) );
addField( pfTr_duration = new cDurationField (
this, "duration", "Duration", 60 ) );
addField( pfTr_title = new cTextField (
this, "title", "Title", 150 ) );
addField( pfTr_language = new cTextField (
this, "language", "Language", 0 ) ) ;
addField( pfTr_lead_performer = new cTextField (
this, "lead_performer" , "Lead performer", 100 ) ) ;
}
[0039] Here the field objects that correspond to the data elements of this record type are assigned to the globally accessible pointers declared before the cTrackRecord: :init() function, which are used in the program code to refer to their corresponding data elements. The names of these global pointers begin with the prefix "pfTr " to mark them as pointers to the fields of a track record.
[0040] The constructors used here for the various cField subclasses are of the form cField( cRecord* pRec, QString sName4 Schema, QString sName4Display,
int nDisplayWidth, bool bMultiple = false )
[0041] The arguments, in order, determine certain properties of the field object:
(1) pRec: a pointer to the applicable prototype record
(2) sName4Schema: the name of the field for the purpose of a record schema for this record type. A schema for a particular version of the record can be assembled by creating a sequential list of these names for the fields of a record, and this sequence may be compared to the corresponding sequences for other versions.
(3) sName4Display: the "generic" name for the field, for display to human users.
(4) nDisplayWidth: the default width, in pixels, for displaying the field (as in a grid).
(5) bMultiple: if true, this is a multiple-valued field; if false, a single-valued (scalar) field
[0042] In addition to the above elements and the virtual size function discussed above, field classes have the following virtual functions, defined at appropriate levels of the field class hierarchy:
(1) write and read functions for serializing the value(s) of the field, each taking as arguments a record pointer and a pointer to an object representing a file, stream or similar means of serialization.
virtual void cField : : read ( cRecord* pRec, cIO* pIO ) ;
virtual void cField :: write ( cRecord* pRec, cIO* pIO ) ;
A variable-length value such as a string can be terminated, if feasible, with a null character, or preceded by an integer value representing the length of the data value. The values of a multiple-valued field can be preceded by an integer value representing the number of values. Values can also be serialized in various self- describing forms, incorporating their string-valued field names (as in various forms of extensible markup language (XML); the sName4Schema property mentioned above can be used for this purpose.
(2) A display function or functions, each taking a record pointer and an optional index as arguments, that return string, tabular or graphic values (or references thereto) containing a form of a data element that can be displayed to a human user.
(3) An optional display width for tabular display formats. [0043] For direct access to the data elements of any record type, the cRecord class is provided with get and put functions, respectively, for retrieving and setting the values of a record's data elements, representing such values in a convenient, appropriate form for various field classes: qint32 cRecord : : get ( const clntField* pFld, int index = -1 ) ;
void cRecord :: put ( const clntField* pFld, int iValue, int index = -1 ) ;
qint64 cRecord :: get ( const cInt64Field* pFld, int index = -1 ) ; void cRecord :: put ( const cInt64Field* pFld, qint64 iValue,
int index = -1 ) ;
QDateTime cRecord :: get ( const cTimeField* pFld, int index = -1 ) ; void cRecord :: put ( const cTimeField* pFld, QDateTime tValue,
int index = -1 ) ;
QDateTime cRecord :: get ( const cTimeField* pFld, int index = -1 ) ; void cRecord :: put ( const cTimeField* pFld, QDateTime tValue,
int index = -1 ) ;
QString cRecord :: get ( const cTextField* pFld, int index = -1 ) ; void cRecord :: put ( const cTextField* pFld, QString sValue,
int index = -1 ) ;
tTimeSpan cRecord :: get ( const cDurationField* pFld, int index = - 1 ) ;
void cRecord :: put ( const cDurationField* pFld, tTimeSpan tValue, int index = -1 ) ;
[0044] In these functions nlndex is the (0-based) index of the desired value for a multiple-valued field; the default value of -1 applies only to a scalar field.
[0045] It should be noted that object classes derived from cRecord and cField are "normal" object classes that can have data members and methods independent of the apparatus described here.
Serialization
[0046] The cRecord class has write and read functions, similar to those of the cField class, for serializing the set of data element values of any object directly or indirectly derived from cRecord, each taking as an argument a pointer to an object representing a file, stream or similar means of serialization: void cRecord : : read ( cIO* pIO ) ;
void cField :: write ( cIO* pIO ) ;
[0047] Reading is performed by calling the read function of each constituent field in order (e.g., in the order in which the fields were added to the prototype record), and writing is performed by calling the write function of the each constituent field in the same order. Where a self-describing syntax, such as XML, is used for serialization, the sequence of field values can be enclosed in a record value, using a unique string-valued name to represent the record type.
[0048] Records serialized in this manner can be freely mixed, without loss of intelligibility, with the serialization of other objects such as integers and strings.
[0049] The present application provides flexible automated support for objects directly or indirectly derived from cRecord to be stored in and retrieved from relational databases.
The Object-Relational Interface: Field Maps and Table Maps
[0050] Rather than generating entire SQL statements or queries (which are generally inaccessible to applications programmers) in the manner of the recordset/dataset objects used in existing technology, the present application automates the inclusion in SQL statements (coded by applications programmers) of the table and column names and the data values that correspond to a record object's fields. The present application also automates the conversion of the results of such queries into updated data values in the record objects involved.
[0051] A particular relational database can store the scalar fields of a particular record class either in a single table or in multiple tables. In either case, the scalar fields of a single record are stored in a single row in each table. The relationship, if any, of the primary keys for these various rows is a matter of database design.
[0052] A form of SQL statement to insert a new row into a relational database is:
INSERT INTO table_name (columnl, column2, column3 , ... )
VALUES (valuel, value2, value3, ...) [0053] A form of SQL statement to update an existing row in a relational database is:
UPDATE table_name
SET columnl=value, column2=value2 , ...
WHERE some_column=some_value
[0054] A form of SQL statement to retrieve a row or a set of records from a relational database is:
SELECT columnl, column2, column3, ...
FROM table_name WHERE condition
[0055] Where a record is stored in multiple tables, an INSERT or UPDATE statement is used for each table, and a JOIN expression involving two or more tables is substituted for "table name" in a SELECT statement:
SELECT aliasn . columnl , aliasn . column2 , aliasn . column3 , ...
FROM table_namel aliasl
JOIN table_name2 alias2
ON table_namel . column_name=table_name2. column_name
[0056] JOINs can be concatenated to involve three or more tables; the aliasn expressions shown here identify the particular table from which each column is taken.
[0057] The present application enables all of the above kinds of SQL statements to be coded directly by applications programmers, with the enumerated column names and values accurately and reliably supplied by the following automated means.
[0058] A field map can be constructed to map a scalar field of a record to the name of the corresponding column of a relational database table: cDBFieldMap : : cDBFieldMap ( cField* pField, QString sDBFieldName, bool bSuppressKey ) ;
where bSuppressKey is true if (and only if) the field is a primary-key field, which is suppressed in INSERT statements.
[0059] The set of a record's scalar fields stored in a particular table is reflected in a table map that can be built by calling the addField() function of the table-map class cDBTableMap once for each such field to construct a new field map and add it to the table map cDBFieldMap* cDBTableMap : : addField ( cField* pField, QString sDBFieldName, bool bSuppressKey = false ) ;
[0060] A multiple field map is used to store and retrieve the contents of a multiple- valued field in a "many-to-many" target table having columns for (1) a target field holding the data value, (2) an ID field holding the integer primary key value of the record in the source table that holds the scalar fields of the record, and optionally (3) a sequence field, the (zero-based) integer index of the value. Its constructor declaration follows: cDBMultipleFieldMap : : cDBMultipleFieldMap ( cField* pField,
QString sTargetFieldName, QString sTargetTableName,
QString sIDFieldName, QString sSequenceFieldName = "" ) : cDBFieldMap ( pField, sTargetFieldName, false ),
m_sTargetTableName ( sTargetTableName ) ,
m_sIDFieldName ( sIDFieldName ),
m_sSequenceFieldName ( sSequenceFieldName ) { }
Here cDBMultipleFieldMap is implemented as a subclass of cDBFieldMap.
[0061] In the absence of a sequence field, a multiple field map can specify an SQL ORDER BY specification to determine the order of the values (array indices) in the loaded record.
[0062] The mapping of a record type to a relational database generally requires a table map for each database table storing the record's scalar fields and a multiple field map for each multiple-valued field. These can be registered in a database record type object (class cDBRecordType) that can be mapped to, or otherwise associated with, the corresponding record type (cRecordType) object. A table map can be constructed and added to a database record type object using: cDBTableMap* addTable ( QString sDBTableName, QString sAlias = ""
) ;
[0063] The optional argument sAlias supplies an alias for this table (as discussed above) to be used in multiple-table SELECT statements involving JOINs.
[0064] A multiple field map can be constructed and added to a database record type object using: cDBMultipleFieldMap* cDBRecordType : : addMultipleField ( cField* pField,
QString sTargetFieldName, QString sTargetTableName,
QString sIDFieldName, QString sSequenceFieldName ) ;
[0065] The following code can be used to build a database record type object to prepare for the storage and retrieval of a music track record (class cTrackRecord) in a relational database, using a single table for the scalar fields: void buildTrack ( )
{
cDBRecordType* pType = cDBRecordType :: get ( TRACK_RECORD );
cDBTableMap* pTMap = pType->addTable ( "tracks" );
pfmGlobalTrackID = pTMap->addField ( pfTr_GlobalID, "track_id", true ) ;
pTMap->addField ( pfTr_ArtistID, "artist_id" );
pTMap->addField ( pfTr_TrackID, "artist_track_id" );
pTMap->addField ( pfTr_composer, "composer_name" ) ;
pTMap->addField ( pfTr_duration, "duration_msec" ) ;
pTMap->addField ( pfTr_title, "track_title" );
pTMap->addField ( pfTr_language, "track_language" ) ;
pTMap->addField ( pfTr_lead_performer, "lead_performer_name" ) ; pType->addMultipleField ( pfTr_genre, "genre_id3tag" ,
"tracks_genres " , "track_id", "genre_order" ) ;
}
[0066] The following code can be used to build a database record type object to prepare for the storage and retrieval of an artist record (class cArtistRecord) in a relational database, using multiple tables for the scalar fields: void buildArtist ( )
{
cDBRecordType* pType = cDBRecordType :: get ( ARTIST_RECORD ); cDBTableMap* pTMap = pType->addTable ( "people", "p" ); pTMap->addField ( pfArt_ArtistID, "person_id" );
pTMap = pType->addTable ( "people_roles " , "pr" );
pTMap->addField ( pfArt_ArtistName, "role_name" );
pTMap->addField ( pfArt_WebAddress , "website_url " );
pType->addMultipleField ( pfArt_genre, "genre_id3tag" ,
"people_roles_genres " , "people_roles_id" , "genre_order" ) ;
}
[0067] To work with the values of data elements in SQL queries and their results, subclasses of cField can have virtual functions, defined at appropriate levels of the cField class hierarchy, to format the values of their data elements from internal object form into the string form used in SQL statements for a particular database, and to parse the column values from the results of SQL queries (generally supplied as strings) into the field object's internal object form: virtual QString cField : : sqlFormat ( cDB* pDB, cRecord* pRec,
int index = -1 ) = 0;
virtual void cField :: sqlParse ( cDBQuery* pQuery, int nColumn, cRecord* pRec, int index = -1 ) = 0;
[0068] Besides the record and index arguments (the default index value of -1 applying in the case of scalar fields), arguments are illustrated here for a particular database (class cDB) and a particular database query (class cDBQuery) whose result is to be parsed.
[0069] Both sqlFormat() and sqlParse() are pure virtual functions that need to be defined at appropriate levels of the cField hierarchy for all fields used in records stored in a relational database.
[0070] Two notes on sqlFormat() and sqlParse(): (1) Similar functions can be provided to perform any conversions required to use the parameterized or "prepared" SQL statements provided by some APIs. (2) Although these functions are generally declared in the header files common to all modules using this data infrastructure, these functions can be implemented as empty "stubs" in modules that do not use a relational database.
[0071] Three functions, methods of cDBTableMap, can be used to generate the enumerated column names and values used for scalar fields in SQL INSERT, UPDATE and SELECT statements executed on a single database table:
QString cDBTableMap :: listFields ( bool blnserting = false ) ; returns a comma-separated list of column names, suppressing the primary-key column when blnserting is passed as true, e.g.:
QString cDBTableMap :: listlnsertValues ( cDB* pDB, cRecord *pRec ); returns a comma-separated list of field values, using the fields' sqlFormat() functions and omitting any primary-key column; QString cDBTableMap : : listUpdateValues ( cDB* pDB, cRecord* pRec ); returns a comma-separated list of field=value pairs, using the fields' sqlFormat() functions.
[0072] The order of fields used by these functions is the order in which the fields were added to the table map using cDBTableMap: :addField(). The same order of fields is used by the function void cDBTableMap :: parseRow ( cDBQuery* pQuery, cRecord* pRec,
int index = 0 ) ; to update the applicable fields in a record with the result of a query by calling the sqlParse() function of each field in order on the string returned by the API's parsing function applied to the result of the given database query.
[0073] All four of these functions have counterparts for database record types, which cover all of the scalar fields of the given record:
QString cDBRecordType : : listFields ( bool blnserting = false ) ;
QString cDBRecordType :: listlnsertValues ( cDB* pDB, cRecord *pRec
) ;
QString cDBRecordType :: listUpdateValues ( cDB* pDB, cRecord* pRec
) ;
void cDBRecordType :: parseRow ( cDBQuery* pQuery, cRecord* pRec ) ;
[0074] The first three functions call their counterparts under cDBTableMap for each table to return comma-separated lists of their column names and values, as applicable, in the order in which the corresponding table maps were added to the database record type object. cDBRecordType ::parseRow() calls cDBTableMap ::parseRow() for each table (making the only actual use of the index argument) to update all of the scalar fields of the record.
[0075] Multiple-valued fields can be conveniently written to and read from their target tables using two methods of the class cField. bool cField : : sqlWriteMultiple ( cDB* pDB, cRecord *pRec,
int i!DFieldValue ) ; updates the applicable rows of a multiple-valued field's target table (as identified in its multiple field map) to reflect the field's values. It does so by first deleting all of the target table's rows for the given record by execuring an SQL statement of the form
DELETE FROM sTargetTableName WHERE sIDFieldName = ilDFieldValue where ilDFieldValue is the primary-key value for pRec, then executing for each index value an SQL statement of the form
INSERT INTO sTargetTableName (sIDFieldName, sTargetFieldName,
sSequenceFieldName) VALUES (ilDFieldValue,
sqlFormat ( pDB, pRec, index ), index);
[0076] The reverse function, bool cField: : sqlReadMultiple ( cDB* pDB, cRecord *pRec,
int ilDFieldValue ) ; updates a multiple-valued field in the given record pRec to reflect all of the field's current values for pRec in the field's target table. It does so by first clearing the field's values, then retrieving all of the target table's rows for the given record by executing an SQL statement of the form
SELECT sTargetFieldName FROM sTargetTableName WHERE sIDFieldName ilDFieldValue ORDER BY sSequenceFieldName; then updating the values using the field's sqlParse() function on the string value returned for each row in turn.
[0077] As with other database-related methods of cField, sqlWriteMultiple() and sqlReadMultiple() can be defined as empty "stubs" in modules that do not use a relational database.
[0078] All of the multiple-value fields of a record can be saved to a database by calling the function bool cDBRecordType : : saveMultipleFields ( cDB* pDB, cRecord* pRec
) ; which calls sqlWriteMultiple() using the field pointer of each of its multiple table maps.
[0079] Similarly, all of the multiple-value fields of a record can be updated from a database by calling the function bool cDBRecordType : : loadMultipleFields ( cDB* pDB, cRecord* pRec which calls sqlWriteMultipleQ using the field pointer of each of its multiple table maps.
[0080] Following are examples of the use of some of the above functions in constructing SQL statements, performing the tasks of updating and retrieving a track record, using the same generic relational-database API wrapper referred to in the previous examples: int queryUpdateTrack ( cTrackRecord* pTRec )
{
cDBRecordType* pTrackType = cDBRecordType :: get ( TRACK_RECORD
) ;
cDBTableMap* pTMap = pTrackType->getTableMap ( sTableName ); QString sQuery;
int iGlobalTrackID = pTRec->get ( pfTr_GlobalID );
if ( iGlobalTrackID =< 0 )
{
QTextStream ( &sQuery ) « "SELECT " «
pfmGlobalTrackID->getDBFieldName () « " FROM " « sTableName « " WHERE artist_id = " «
pTRec->get ( pfTr_ArtistID ) « " AND artist_track_id = "
«
pTRec->get ( pfTr_TrackID ) «
cDBQuery* pQ = gDB->query( sQuery, true ) ;
if ( !pQ )
return -1;
if ( pQ->fetchRow ( ) )
{
pfmGlobalTrackID->parseRow ( pQ, pTRec ) ;
iGlobalTrackID = pTRec->get ( pfTr_GlobalID );
assert ( ! pQ->fetchRow ( ) ) ; // should be only one row
}
pQ->free ( ) ;
if ( iGlobalTrackID < 0 ) // i.e., unchanged, because not found
return 0;
}
sQuery . clear ( ) ;
QTextStream ( &sQuery ) « "UPDATE " « sTableName « " SET "
«
pTMap-MistUpdateValues ( gDB, pTRec ) « " WHERE track_id = " « iGlobalTrackID «
if ( ! gDB->doQuery ( sQuery, true ) )
return -iGlobalTrackID;
if ( !pTrackType->saveMultipleFields ( gDB, pTRec,
iGlobalTrackID ) )
return -iGlobalTrackID;
gDB->commit ( ) ;
return iGlobalTrackID;
}
int queryRetrieveTrack ( cTrackRecord* pTRec )
{
QString sTableName = "tracks";
cDBRecordType* pTrackType = cDBRecordType : : get ( TRACK_RECORD
) ;
cDBTableMap* pTMap = pTrackType->getTableMap ( sTableName ); QString sQuery;
int iTrackID = pTRec->get ( pfTr_GlobalID );
QTextStream ( &sQuery ) « "SELECT " « pTMap-MistFields ( ) «
" FROM " « sTableName « " WHERE ";
if ( iTrackID > 0 )
QTextStream ( &sQuery ) « "global_id = " « iTrackID « else
QTextStream ( &sQuery ) « "artist_id = " «
pTRec->get ( pfTr_ArtistID ) « " AND artist_track_id =
«
pTRec->get ( pfTr_TrackID ) « ";";
cDBQuery* pQ = gDB->query( sQuery, true );
if ( !pQ )
return -1;
if ( pQ->fetchRow ( ) )
{
pTMap->parseRow ( pQ, pTRec );
iTrackID = pTRec->get ( pfTr_GlobalID );
assert ( iTrackID > 0 );
assert ( ! pQ->fetchRow ( ) ); // should be only one row if ( !pTrackType->saveMultipleFields ( gDB, pTRec, iGlobalTrackID ) )
return -1;
}
pQ->free ( ) ;
return iTrackID;
Total Database Automation
[0081] The apparatus of formatting and parsing functions, field and table maps, and database record type objects described here provides a complete way of codifying and automating the interface between the internal object and relational states of data, which can accommodate a wide variety of relational database designs.
[0082] The canonical set of operations known as CRUD— create, read, update, delete— can be similarly automated for cRecord-derived objects stored in a relational database if the cDBRecordType object can identify an integer primary-key field for each such record type, whose value uniquely identifies each record of that type. Such a primary-key field can often be chosen from among the columns of one or more database tables corresponding to a record type. When no such column exists, a primary key can be provided as a local database field (class cLocalDBField, derived from cField), which is carried internally in cRecord-derived objects in a single application module and is used as a primary key in a local database attached to that module, but not serialized for transmission to other modules. Local database fields have other uses, e.g., to indicate a record status that has significance only for a single module. A record of a type without a primary-key field can often be uniquely identified by combining the values of a set of fields termed compound-key fields.
[0083] If every database record type has a primary key field, then functions can be provided for the entire CRUD repertoire, i.e.:
(1) inserting a record represented by a record object into a relational database,
obtaining a primary-key value and assigning it to the primary-key field of the record object;
(2) loading a record object, identified by its primary-key value or a set of compound- key values, with data values from a relational database;
(3) updating a record object, identified by its primary-key value or by a pointer to a cRecord, in a relational database; and
(4) removing a record, identified by its primary-key value or by a pointer to a
cRecord, from a relational database
[0084] The implementation of these functions (and their integration with model-view architecture) is discussed below under "Datasets, Datastores and Relational Datastore Indexes." [0085] Where there is no need to accommodate an existing relational database, a self- building local relational database can be created to store and retrieve any or all of an application module's cRecord-derived records, with some further adjustments:
(1) Every cField-derived class can identify a string-valued data type that may be used in SQL, e.g., "INTEGER" or "TEXT".
(2) The cDBRecordType object can carry a table name.
(3) The cDBRecordtype object can identify any foreign-key constraints (discussed below under "Complex Record Objects") using pointers to the cField objects involved.
(4) The cDBRecordType object carries a list of any local database fields, which is used in storing and retrieving database records.
[0086] A cDBRecordType object can be created for each stored record type, storing its scalar data elements in a single table represented by a table map that carries a field map for each scalar field, using the corresponding cField object's sName4Schema property as the corresponding column name. A cDBMultipleFieldMap can be created for each muliple-valued field, giving system-generated names to the target table and its three columns: For example, the target name can combine the name of the source table and the field's sName4Schema property, the ID field column can be assigned the name of the cDBRecordType 's primary-key field, the column containing the data value can be assigned the field's sName4Schema property, and the sequence field column can be assigned the name "SEQUENCE".
[0087] A complete set of tables can be created using SQL CREATE TABLE statements prepared from each cDBRecordType, specifying:
(1) a table name for the record type;
(2) names and data types for each scalar-valued column;
(3) table names, column names and data types for target tables associated with
multiple-valued fields; and
(4) any foreign-key constraints. Datasets, Datastores and Relational Datastore Indexes
[0088] In the present example system, a track record can appear not only in the set of all track records (or any selected subset thereof), but also in multiple playlists.
[0089] In terms of the model-view architecture used in computing applications that display data to a human user— in which a plurality of views of data collections (e.g., various lists or grids displaying data objects) can display data from a single internal model giving access to a collection of data objects— each of these distinct collections of track records would correspond to a different model.
[0090] Each of these models can be associated with an ordered collection of pointers to objects of a single cRecord subclass (with additional properties, described below) termed a dataset (class cDataset; not to be confused with the recordset/dataset objects referred to in the prior art). The separation of models from datasets allows models to hold values modified by human users that may later be committed to their datasets.
[0091] Each distinct record can be represented in internal memory by a single cRecord object, represented by a single cRecord* pointer in any number of datasets, ensuring that changes to the record's data elements will be reflected in all such datasets. Even with this benefit, there are two significant challenges:
(1) If records can be freely loaded into memory from a database or other data store, care must be taken to ensure that loaded records do not duplicate any records already residing in memory.
(2) Changes to a record must be propagated to all datasets containing the record, so that the associated models can update their views.
[0092] Both of these challenges can be met as follows:
(1) A datastore class (cDatastore) is given control over the CRUD operations, with virtual functions for loading, updating, inserting and removing records.
cDatastore has a relational datastore subclass (cDBDatastore) that works with a relational database and implements the CRUD functions as detailed above, using the field-map/table-map/database-record-type apparatus. Any dataset can be associated with a datastore, relational or not. (2) Each object of the cDBDatastore class maintains a relational datastore index (class cDBIndex) for each record type, mapping a (unique) pointer to each record held in memory to the record's primary-key value. All CRUD operations update this index as appropriate.
(3) The system maintains a list of all datasets for each record type.
(4) In addition to being implemented by the datastore classes, the CRUD operations are also implemented by the cDataset class:
a. Before inserting a record into a dataset associated with a relational
datastore, an attempt is made to insert it into the database. If the attempt succeeds, it supplies a primary-key value for the record, which is placed in the record's primary-key field. The relational datastore index is updated with a pointer to the record and record's primary-key value. b. Before loading a record from a relational datastore 's database into a
dataset, the relational datastore index is checked to see whether a record already resides in memory; if so, the resident record is used rather than being (re-)loaded from the database.
c. When a record in a dataset associated with a datastore is modified, the datastore is updated to reflect those changes. The system's list of datasets for the dataset' s type is used to notify all other datasets of that type of the modification, so that they can update their models, which will in turn update their views.
d. Before purging a record associated with a relational datastore from the system, an attempt is made to remove it from the database. If successful, its entry is removed from the relational datastore index. The system's list of datasets for the dataset' s type is used to notify all other datasets of that type of the deletion, so that they can update their models, which will in turn update their views.
Complex Record Objects
[0093] The record object class representing playlists in this example system, cPlaylistRecord, is a subclass of the complex record object class, cDBComplexRecord, which covers record objects with at least one (multiple-valued) data element that represents an ordered collection of other cRecord-derived objects termed component records. Each such collection in a complex record object is represented by
(1) a multiple-valued integer component field (of class clntField) containing primary- key values for the records referred to, in the desired order, and (2) a corresponding component dataset associated with a relational datastore, containing pointers to the records referred to, in the same desired order.
[0094] Complex record objects must be stored in a relational database, and any dataset containing them must be associated with the same relational datastore as their component datasets.
[0095] A foreign-key constraint is established for each component field with a primary-key column in a table where the component records are stored.
[0096] Component datasets can be associated with models as described above to display their record data.
[0097] Functions are provided for linking component fields with component datasets, void cDBComplexRecord : : addDataset ( cDataset*& pDS, cField *pField ) ; accessing component datasets given a component field pointer, cDataset* cDBComplexRecord :: getDataset ( cField* pField ) ; and loading component datasets from the datastore, void cDBDatastore : : loadFieldBasedDataset ( cDBComplexRecord* pDBCRec,
cField* pField, cDataset* pDS ) ; all using the apparatus and methods described above.
[0098] Subclasses of cDBComplexRecord are implemented so that loading a complex record from a datastore automatically loads all of its component fields, and saving a complex record to its datastore automatically saves all of its component fields.
BLOB Fields
[0099] One important subclass of the field object class cField, is cBlobField, which handles references to images and/or other binary large objects (BLOBs). Each distinct BLOB can be identified by a unique integer ID number of system-wide scope, and the contents of a cBlobField is one or more such BLOB ID values (an ID value of 0, if not assigned to any actual BLOB, can serve as a null value). BLOBs can be stored:
(1) in memory as a BLOB map that maps each unique ID to its corresponding BLOB; and
(2) in a dedicated BLOBS table in a relational database, having an integer- valued column containing IDs and a BLOB-valued column containing BLOBs.
[00100] For display or other purposes, an integer BLOB ID value in a cRecord object can be used to retrieve the corresponding BLOB from the BLOB map; or, if not in the BLOB map, to load the BLOB into the BLOB map from the BLOBs table.
[00101] The BLOB map and the BLOBS table can incorporate additional fields such as the dates and times of a BLOB's creation and most recent revision, which can be of use in updating BLOB values.
[00102] A cBlobField value can be serialized as follows:
(1) first, the integer BLOB ID
(2) next, an integer indicated the BLOB's size in bytes; or 0 to indicate that the
BLOB is not being explicitly serialized here (this can be used in cases where the identical blob has already been serialized in this transmission or file).
(3) finally, for non-zero size, the BLOB's contents.
[00103] FIG. 3 schematically shows an embodiment of the relationships between the different canonical states of data and how the different states of data may be communicated between components.
[00104] In one embodiment of the present application, pure data values (which should have no functionality other than the infrastructure's own data-handling methods) can be separated from object functionality. Subclassing of field and record objects can be provided for functionality independent of data contents or values.
[00105] The examples provided in this application have been coded in the multi- platform C++-language environment Qt, in which QString is a string class and QVector is a template-based array class (in this case holding multiple integer-valued genre tags). tTimeSpan is a "custom" data type defined for this particular system: typedef unsigned long tTimeSpan;
[00106] Embodiments within the scope of the present application include program products having machine-readable media for carrying or having machine-executable instructions or data structures stored thereon. Machine-readable media can be any available non-transitory media that can be accessed by a general purpose or special purpose computer or other machine with a processor. By way of example, machine- readable media can comprise RAM, ROM, EPROM, EEPROM, CD-ROM or other optical disk storage, magnetic disk storage or other magnetic storage devices, or any other medium which can be used to carry or store desired program code in the form of machine-executable instructions or data structures and which can be accessed by a general purpose or special purpose computer or other machine with a processor. When information is transferred or provided over a network or another communication connection (either hardwired, wireless, or a combination of hardwired or wireless) to a machine, the machine properly views the connection as a machine-readable medium. Combinations of the above are also included within the scope of machine-readable media. Machine-executable instructions comprise, for example, instructions and data which cause a general purpose computer, special purpose computer, or special purpose processing machines to perform a certain function or group of functions.
[00107] Although the figures herein may show a specific order of method steps, the order of the steps may differ from what is depicted. Also, two or more steps may be performed concurrently or with partial concurrence. Variations in step performance can depend on the software and hardware systems chosen and on designer choice. All such variations are within the scope of the application. Likewise, software implementations could be accomplished with standard programming techniques with rule based logic and other logic to accomplish the various connection steps, processing steps, comparison steps and decision steps. [00108] It should be understood that the embodiments illustrated in the figures and described herein are offered by way of example only. Other substitutions, modifications, changes and omissions may be made in the design, operating conditions and arrangement of the embodiments without departing from the scope of the present application. Accordingly, the present application is not limited to a particular embodiment, but extends to various modifications that nevertheless fall within the scope of the appended claims. It should also be understood that the phraseology and terminology employed herein is for the purpose of description only and should not be regarded as limiting.
[00109] It is important to note that the construction and arrangement of the present application as shown in the various embodiments is illustrative only. Although only a few embodiments have been described in detail in this application, those who review this application will readily appreciate that many modifications are possible (e.g., variations in sizes, dimensions, structures, shapes and proportions of the various elements, values of parameters (e.g., ranges, sequences, enumerations, frequencies, durations, etc.), mounting arrangements, use of materials, orientations, data formats, implementation platforms, etc.) without materially departing from the novel teachings and advantages of the subject matter described in the application. For example, elements shown as integrally formed may be constructed of multiple parts or elements, the position of elements may be reversed or otherwise varied, and the nature or number of discrete elements or positions may be altered or varied. The order or sequence of any process or method steps may be varied or re-sequenced according to alternative embodiments. It is, therefore, to be understood that the appended claims are intended to cover all such modifications and changes. In the claims, any means-plus-function clause is intended to cover the structures described herein as performing the recited function and not only structural equivalents but also equivalent structures.
[00110] Furthermore, in an effort to provide a concise description of the exemplary embodiments, all features of an actual implementation may not have been described (i.e., those unrelated to the presently contemplated best mode of carrying out the invention, or those unrelated to enabling the claimed invention). It should be appreciated that in the development of any such actual implementation, as in any engineering or design project, numerous implementation specific decisions may be made. Such a development effort might be complex and time consuming, but would nevertheless be a routine undertaking of design, fabrication, manufacture, and implementation for those of ordinary skill having the benefit of this disclosure, without undue experimentation.

Claims

1. An object-oriented data infrastructure to convert data between different canonical states comprising:
a microprocessor;
a memory in communication with the microprocessor;
at least one record object residing in the memory and including a plurality of elements, the at least one record object being defined by a record type, the record type having a predetermined schema comprising at least one field object; and
the at least one field object accesses and manipulates the plurality elements of the at least one record object and performs data conversions between the canonical states.
2. The object-oriented data infrastructure of claim 1 wherein the predetermined schema comprises an ordered set of field objects.
3. The object-oriented data infrastructure of claim 1 wherein the plurality of elements comprises at least one data element.
4. The object-oriented data infrastructure of claim 1 wherein the at least one field object has a preselected name to identify the at least one field object in the predetermined schema.
5. The object-oriented data infrastructure of claim 1 further comprising a field class associated with the at least one field object, the field class comprises one or more data-conversion functions.
6. The object-oriented data infrastructure of claim 5 wherein the one or more data conversion functions include parsing and formatting functions for data representation in SQL.
7. The object-oriented data infrastructure of claim 1 wherein the at least one field object comprises one or more functions to list fields and values for inclusion in SQL queries and one or more functions to parse returned values in order.
8. The object-oriented data infrastructure of claim 1 wherein the predetermined schema for the at least one record object comprises at least one first field object associated with a data element of the at least one record object and at least one second field object associated with functionality for the at least one record object.
9. The object-oriented data infrastructure of claim 8 wherein the at least one first field object is independent of the at least one second field object.
10. The object-oriented data infrastructure of claim 1 wherein the at least one record object is identified by a primary-key
11. The object-oriented data infrastructure of claim 10 wherein the primary key is from a unique integer valued field in an existing relational database table.
12. The object-oriented data infrastructure of claim 10 wherein the integer primary key is assigned from a unique combination of field values to form a compound key.
13. The object-oriented data infrastructure of claim 10 wherein the primary key is used for indexing the at least one record object to ensure sharing of unique data records in the memory.
14. The object-oriented data infrastructure of claim 13 wherein the at least one record object comprises a dataset record object and a datastore record object, each of the dataset record object and the datastore record object uses the primary key for indexing.
15. The object-oriented data infrastructure of claim 1 wherein the at least on record object comprises a complex record object, the complex record object, when loaded into the memory, maintains datasets of referenced record objects to be selectively loaded into the memory.
16. The object-oriented data infrastructure of claim 1 wherein the at least one field object comprises a BLOB field object to handle references to images and other binary large objects.
PCT/US2014/029954 2013-03-15 2014-03-15 Object-oriented data infrastructure WO2014145230A1 (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US201361790499P 2013-03-15 2013-03-15
US61/790,499 2013-03-15

Publications (1)

Publication Number Publication Date
WO2014145230A1 true WO2014145230A1 (en) 2014-09-18

Family

ID=51537915

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/US2014/029954 WO2014145230A1 (en) 2013-03-15 2014-03-15 Object-oriented data infrastructure

Country Status (1)

Country Link
WO (1) WO2014145230A1 (en)

Cited By (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2017070580A1 (en) * 2015-10-23 2017-04-27 Oracle International Corporation Ability to group multiple container databases as a single container database cluster
US10360269B2 (en) 2015-10-23 2019-07-23 Oracle International Corporation Proxy databases
US10467202B2 (en) 2017-07-21 2019-11-05 Bank Of America Corporation System for multi-release and parallel development of a database
US10572551B2 (en) 2015-10-23 2020-02-25 Oracle International Corporation Application containers in container databases
US10606578B2 (en) 2015-10-23 2020-03-31 Oracle International Corporation Provisioning of pluggable databases using a central repository
US10628422B2 (en) 2015-10-23 2020-04-21 Oracle International Corporation Implementing a logically partitioned data warehouse using a container map
US10635658B2 (en) 2015-10-23 2020-04-28 Oracle International Corporation Asynchronous shared application upgrade

Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20010049693A1 (en) * 1999-01-04 2001-12-06 Robert C. Pratt Mapping binary objects in extended relational database management systems with relational registry
US6658625B1 (en) * 1999-04-14 2003-12-02 International Business Machines Corporation Apparatus and method for generic data conversion
US20050091251A1 (en) * 2003-10-22 2005-04-28 Conformative Systems, Inc. Applications of an appliance in a data center
US7861226B1 (en) * 2006-03-16 2010-12-28 Avaya Inc. Constraint solver to code based test data generation for improving software reliability and security
US20110196844A1 (en) * 2006-11-01 2011-08-11 Ab Initio Technology Llc Managing storage of individually accessible data units
WO2011126995A1 (en) * 2010-04-05 2011-10-13 Google Inc. Columnar storage representations of records

Patent Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20010049693A1 (en) * 1999-01-04 2001-12-06 Robert C. Pratt Mapping binary objects in extended relational database management systems with relational registry
US6658625B1 (en) * 1999-04-14 2003-12-02 International Business Machines Corporation Apparatus and method for generic data conversion
US20050091251A1 (en) * 2003-10-22 2005-04-28 Conformative Systems, Inc. Applications of an appliance in a data center
US7861226B1 (en) * 2006-03-16 2010-12-28 Avaya Inc. Constraint solver to code based test data generation for improving software reliability and security
US20110196844A1 (en) * 2006-11-01 2011-08-11 Ab Initio Technology Llc Managing storage of individually accessible data units
WO2011126995A1 (en) * 2010-04-05 2011-10-13 Google Inc. Columnar storage representations of records

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
JENKOV, J., JAVA REFLECTION - FIELDS., Retrieved from the Internet <URL:http://tutorials.jenkov.com/java-reflectionlfields.html> *

Cited By (9)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2017070580A1 (en) * 2015-10-23 2017-04-27 Oracle International Corporation Ability to group multiple container databases as a single container database cluster
US10360269B2 (en) 2015-10-23 2019-07-23 Oracle International Corporation Proxy databases
US10572551B2 (en) 2015-10-23 2020-02-25 Oracle International Corporation Application containers in container databases
US10606578B2 (en) 2015-10-23 2020-03-31 Oracle International Corporation Provisioning of pluggable databases using a central repository
US10628422B2 (en) 2015-10-23 2020-04-21 Oracle International Corporation Implementing a logically partitioned data warehouse using a container map
US10635658B2 (en) 2015-10-23 2020-04-28 Oracle International Corporation Asynchronous shared application upgrade
US10803078B2 (en) 2015-10-23 2020-10-13 Oracle International Corporation Ability to group multiple container databases as a single container database cluster
US10467202B2 (en) 2017-07-21 2019-11-05 Bank Of America Corporation System for multi-release and parallel development of a database
US11157468B2 (en) 2017-07-21 2021-10-26 Bank Of America Corporation System for multi-release and parallel development of a database

Similar Documents

Publication Publication Date Title
WO2014145230A1 (en) Object-oriented data infrastructure
US8321467B2 (en) System and method for communicating between an application and a database
US7877418B2 (en) Schema for sharing relational database types
US7634515B2 (en) Data model and schema evolution
Stadler et al. Making interoperability persistent: A 3D geo database based on CityGML
KR101063625B1 (en) Methods and Systems for Storing State-Specific Health-Related Episode Data and Computer-readable Storage Media
US20040044687A1 (en) Apparatus and method using pre-described patterns and reflection to generate a database schema
CN103425723A (en) Deleting records in a multi-level storage architecture without record locks
CN103425722A (en) Logless atomic data movement
JP2002538546A (en) ABAP Code Converter Specifications
CN103377148A (en) Partial merge
WO2013057937A1 (en) Transformation of complex data source result sets to normalized sets for manipulation and presentation
US20040044989A1 (en) Apparatus and method using pre-described patterns and reflection to generate source code
US20060122973A1 (en) Mechanism for defining queries in terms of data objects
Dadam et al. Advanced Information Management (AIM): Advanced database technology for integrated applications
Michel et al. Translation of Heterogeneous Databases into RDF, and Application to the Construction of a SKOS Taxonomical Reference
Batory GENESIS: a project to develop an extensible database management system
Staudt et al. The role of metadata for data warehousing
Banerjee et al. All your data: the oracle extensibility architecture
Atzeni et al. Data modeling across the evolution of database technology
US7716677B2 (en) System and method for mapping container managed persistence persistent object states to java data object states
Schreiner et al. Boost-histogram: High-Performance Histograms as Objects.
Morishima et al. A data modeling and query processing scheme for integration of structured document repositories and relational databases
Herrin II et al. Schema and tuple trees: An intuitive structure for representing relational data
Gorbach et al. Microsoft SQL server 2008 analysis services unleashed

Legal Events

Date Code Title Description
121 Ep: the epo has been informed by wipo that ep was designated in this application

Ref document number: 14765609

Country of ref document: EP

Kind code of ref document: A1

NENP Non-entry into the national phase

Ref country code: DE

122 Ep: pct application non-entry in european phase

Ref document number: 14765609

Country of ref document: EP

Kind code of ref document: A1