SchemaTableNode.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _DMPROVIDER_SCHEMATABLENODE_H
00014 #define _DMPROVIDER_SCHEMATABLENODE_H
00015 
00021 #include <storage/IndexedDataNode.h>
00022 #include <storage/GenericIterable.h>
00023 #include <storage/MetaDataNode.h>
00024 #include <storage/SDatabase.h>
00025 
00026 #include <support/ICatalog.h>
00027 #include <support/ITable.h>
00028 #include <storage/IReferable.h>
00029 
00030 #include <SchemaDatabases.h>
00031 
00032 #if _SUPPORTS_NAMESPACE
00033 namespace palmos {
00034 namespace dmprovider {
00035 using namespace palmos::storage;
00036 #endif
00037 
00042 B_CONST_STRING_VALUE_SMALL(BV_DATABASE_ID,          "id", );
00043 B_CONST_STRING_VALUE_LARGE(BV_DATABASE_MAX_SIZE,    "max_size", );
00044 B_CONST_STRING_VALUE_LARGE(BV_DATABASE_TYPE,        "type", );
00045 B_CONST_STRING_VALUE_LARGE(BV_DATABASE_ATTR,        "attr", );
00046 B_CONST_STRING_VALUE_LARGE(BV_DATABASE_NAME,        "name", );
00047 
00049 
00062 class BSchemaTableNode : public BMetaDataNode, public BGenericIterable,
00063     public BnCatalog, public BnTable, public BnReferable
00064 {
00065 public:
00066     // --------------------------------------------------------------
00070                                     BSchemaTableNode(   const SContext& context,
00071                                                         const SDatabase& database,
00072                                                         const SString& table,
00073                                                         const SString& keyColumn = SString(),
00074                                                         const SString& refPath = SString());
00075 protected:
00076     virtual                         ~BSchemaTableNode();
00077 public:
00078 
00080     virtual lock_status_t           Lock() const;
00082     virtual void                    Unlock() const;
00084     inline  SContext                Context() { return BMetaDataNode::Context(); }
00086     virtual SValue                  Inspect(const sptr<IBinder>& caller, const SValue& which, uint32_t flags);
00088     virtual void                    InitAtom();
00090             status_t                StatusCheck();
00091 
00093 
00094     // --------------------------------------------------------------
00100 
00102             class CustomColumn;
00103 
00105 
00109     virtual void                    SetMimeType(const SString& value);
00110 
00112             SString                 RowMimeTypeLocked() const;
00113 
00115             status_t                StoreRowMimeTypeLocked(const SString& mimeType);
00116 
00118             SString                 TableName() const;
00119 
00121 
00122     // --------------------------------------------------------------
00126 
00128             class RowNode;
00130             class DataAccessor;
00131 
00133     virtual status_t                LookupEntry(const SString& entry, uint32_t flags, SValue* node);
00134 
00136     virtual status_t                LookupNode(const SString& entry, sptr<RowNode>* outNode);
00137 
00139             sptr<RowNode>           NodeForLocked(uint32_t rowID);
00140 
00142             SString                 EntryNameForLocked(uint32_t rowID) const;
00143 
00145             bool                    RowIDIsValidLocked(uint32_t rowID) const;
00146 
00148 
00149             ssize_t                 ColumnIndexOfLocked(const SString& entry) const;
00150 
00152 
00154             SString                 ColumnNameAtLocked(size_t index) const;
00155 
00157 
00159             type_code               ColumnTypeAtLocked(size_t index) const;
00160 
00162             size_t                  CountColumnsLocked() const;
00163 
00165     virtual void                    MapSQLOrderColumn(SValue* inoutColumnName, SValue* inoutOrder) const;
00166 
00168 
00169     virtual void                    ReportChangeAtLocked(size_t rowid, size_t col, const sptr<IBinder>& editor, uint32_t changes, off_t start=-1, off_t length=-1);
00170 
00172 
00173     // --------------------------------------------------------------
00176 
00177     virtual SValue                  ColumnNames() const;
00178     virtual SValue                  Schema() const;
00179     virtual status_t                CreateRow(SString* name, const SValue& columns, uint32_t flags = 0, sptr<INode>* createdRow = NULL);
00180     virtual status_t                RemoveRow(const sptr<INode>& row);
00181     virtual status_t                AddColumn(const SString& name, uint32_t typeCode, size_t maxSize, uint32_t flags, const SValue& extras);
00182     virtual status_t                RemoveColumn(const SString& name);
00183 
00185 
00186     // --------------------------------------------------------------
00189 
00190     virtual status_t                AddEntry(const SString& name, const SValue& entry);
00191     virtual status_t                RemoveEntry(const SString& name);
00192     virtual status_t                RenameEntry(const SString& entry, const SString& name);
00193     
00194     virtual sptr<INode>             CreateNode(SString* name, status_t* err);
00195     virtual sptr<IDatum>            CreateDatum(SString* name, uint32_t flags, status_t* err);
00196 
00198 
00199     // --------------------------------------------------------------
00202 
00203     virtual SString                 Reference() const;
00204 
00206 
00207     //  ------------------------------------------------------------------
00210 
00212             class QueryIterator;
00213 
00214     virtual sptr<GenericIterator>   NewGenericIterator(const SValue& args);
00215 
00217 
00219     virtual sptr<RowNode>           NewRowNodeLocked(uint32_t rowID);
00220 
00222 
00223 private:
00224                                     BSchemaTableNode(const BSchemaTableNode&);
00225             BSchemaTableNode&       operator=(const BSchemaTableNode&);
00226 
00227     friend class CustomColumn;
00228     friend class DataAccessor;
00229     friend class RowNode;
00230     friend class QueryIterator;
00231 
00232             struct column_info
00233             {
00234                 size_t      id;             // DM id for this column
00235                 size_t      index;          // local index of column
00236                 ssize_t     customIndex;    // if custom column, index into that array; else < 0.
00237                 size_t      maxSize;        // maximum data in column
00238                 SString     name;           // name of column
00239                 type_code   type;           // local type code of column
00240                 uint32_t    dmType;         // DM type code of column
00241                 bool        writable : 1;   // can be modified by clients?
00242                 bool        varsize: 1;     // is this variable-length data?
00243             };
00244 
00245             struct custom_column_info
00246             {
00247                 sptr<CustomColumn>  column;
00248                 SString             name;
00249                 SVector<SString>    baseColumns;
00250                 SVector<size_t>     baseIndices;
00251             };
00252 
00253     static  status_t                build_column_info(const DbTableDefinitionType* table, SVector<column_info>* outColumns);
00254             void                    retrieve_schema();
00255             status_t                new_row_l(const SValue& columns, SString* newName = NULL, sptr<INode>* newRow = NULL);
00256             status_t                add_custom_column(const sptr<CustomColumn>& column, const SString& name, const char** baseColumnNames);
00257             status_t                rem_custom_column(const sptr<CustomColumn>& column, const SString& name);
00258             uint32_t                name_to_rowid_l(const SString& entry) const;
00259             SValue                  entry_key_for_l(uint32_t rowID, status_t* outError) const;
00260 
00261     const   SDatabase                               m_database;
00262     const   SString                                 m_table;
00263     const   SString                                 m_keyColumn;
00264     const   SString                                 m_refPath;
00265 
00266             status_t                                m_status;
00267             DmOpenRef                               m_ref;
00268             SString                                 m_rowMimeType;
00269             SVector<column_info>                    m_columns;
00270             SVector<custom_column_info>             m_customColumns;
00271             SKeyedVector<SString, ssize_t>          m_columnNameToIndex;
00272             SKeyedVector<uint32_t, wptr<RowNode> >  m_nodes;
00273 
00274             SLocker                                 m_accessorsLock;
00275             SSortedVector<wptr<DataAccessor> >      m_accessors;
00276 };
00277 
00278 // --------------------------------------------------------------------------
00279 
00281 
00286 class BSchemaTableNode::CustomColumn : public virtual SAtom
00287 {
00288 public:
00289     // --------------------------------------------------------------
00293                                             CustomColumn(const sptr<BSchemaTableNode>& table);
00294     virtual                                 ~CustomColumn();
00295 
00296     inline  const sptr<BSchemaTableNode>&   Table() const { return m_table; }
00297 
00299 
00300     // --------------------------------------------------------------
00304 
00306             status_t                        AttachColumn(const SString& name, const char** baseColumnNames = NULL);
00307 
00309             status_t                        DetachColumn(const SString& name);
00310 
00312 
00313     // --------------------------------------------------------------
00317 
00319     virtual SValue                          ValueLocked(uint32_t columnOrRowID, const SValue* baseValues, const size_t* columnsToValues) const = 0;
00320     virtual status_t                        SetValueLocked(uint32_t columnOrRowID, const SValue& inValue, SValue* inoutRealValues);
00321 
00323 
00324 private:
00325             const sptr<BSchemaTableNode>    m_table;
00326 };
00327 
00328 // --------------------------------------------------------------------------
00329 
00331 
00335 class BSchemaTableNode::DataAccessor : public virtual SAtom
00336 {
00337 public:
00338     // --------------------------------------------------------------
00342 
00343                                             DataAccessor(const sptr<BSchemaTableNode>& table);
00344 protected:
00345     virtual                                 ~DataAccessor();
00347     virtual void                            InitAtom();
00348 public:
00349 
00350     inline  const sptr<BSchemaTableNode>&   Table() const { return m_table; }
00351 
00353 
00354     // --------------------------------------------------------------
00358 
00359             status_t                        SetColumnsLocked(const SValue& columns, SValue* outSelectedColumns = NULL);
00360             size_t                          CountColumnsLocked() const;
00361             size_t                          ColumnIDLocked(size_t column) const;
00362             const column_info&              ColumnInfoLocked(size_t column) const;
00363 
00365 
00366     // --------------------------------------------------------------
00370 
00371             status_t                        LoadDataLocked(uint32_t rowID, uint32_t flags, SValue* outData, size_t maxDataSize = 256);
00372             SValue                          ColumnValueLocked(uint32_t rowID, size_t column, uint32_t flags, size_t maxDataSize = 2048) const;
00373             size_t                          ColumnSizeLocked(uint32_t rowID, size_t column) const;
00374 
00375             status_t                        SetColumnValueLocked(uint32_t rowID, size_t column, const SValue &value);
00376 
00378 
00379 private:
00380     inline  void                            ensure_column_counts_l() const;
00381             void                            get_column_counts_l();
00382             const column_info&              base_column_info_l(size_t column) const;
00383             const column_info&              custom_column_info_l(size_t column) const;
00384             status_t                        build_mappings_and_indices_l();
00385             status_t                        prep_column_read_l(uint32_t row, const column_info& ci, uint32_t flags, DbSchemaColumnValueType* outData, SValue* intoValue, size_t maxDataSize) const;
00386             status_t                        compute_column_l(uint32_t row, const column_info& ci, uint32_t flags, const SValue* baseValues, const size_t* columnToValue, SValue* intoValue, size_t maxDataSize) const;
00387             status_t                        set_computed_column_value_l(uint32_t row, size_t column, const SValue &inValue);
00388             void                            release_buffers_l();
00389             SValue                          computed_column_value_l(uint32_t rowID, size_t column, uint32_t flags, size_t maxDataSize = 2048) const;
00390 
00391             const sptr<BSchemaTableNode>    m_table;
00392             bool                            m_knowNumColumns;
00393 
00394             // This is the number of columns we need from the database table to compute
00395             // custom columns, but which were not explicitly requested.
00396             size_t                          m_numDepColumns;
00397             // This is the number of columns in the database table whose value we have
00398             // been asked to return.
00399             size_t                          m_numBaseColumns;
00400             // This is the number of columns we need to return which are computed from
00401             // other columns in the database.
00402             size_t                          m_numCustomColumns;
00403             // Mapping from [0..m_numDepColumns..m_numDepColumns+m_numBaseColumns) to
00404             // the index into the table's column info list.
00405             SVector<ssize_t>                m_databaseColumns;
00406             // Mapping from [0..m_numCustomColumns) to the index into the table's
00407             // column info list.
00408             SVector<ssize_t>                m_customColumns;
00409 
00410             // These are constructed by build_mappings_and_indices_l().
00411             SValue                          m_columnNames;
00412             SVector<size_t>                 m_indices;              // [0..m_numBaseColumns..m_numBaseColumns+m_numCustomColumns)
00413             SVector<SValue>                 m_values;               // [0..m_numDepColumns..m_numDepColumns+m_numBaseColumns..m_numDepColumns+m_numBaseColumns+m_numCustomColumns)
00414             SVector<DbSchemaColumnValueType> m_columnData;          // [0..m_numDepColumns..m_numDepColumns+m_numBaseColumns)
00415             SVector<SVector<size_t> >       m_customColumnData;     // [0..m_numCustomColumns)
00416 };
00417 
00418 // --------------------------------------------------------------------------
00419 
00421 
00426 class BSchemaTableNode::RowNode : public BIndexedDataNode, public BnCatalog, public BnReferable, public BSchemaTableNode::DataAccessor
00427 {
00428 public:
00429     // --------------------------------------------------------------
00433                                     RowNode(const SContext& context, const sptr<BSchemaTableNode>& owner, uint32_t rowID);
00434 protected:
00435     virtual                         ~RowNode();
00437     inline  SContext                Context() { return RowNode::Context(); }
00439     virtual SValue                  Inspect(const sptr<IBinder>& caller, const SValue& which, uint32_t flags);
00441     virtual void                    InitAtom();
00443     virtual status_t                FinishAtom(const void* id);
00445     virtual bool                    HoldRefForLink(const SValue& binding, uint32_t flags);
00446 public:
00447 
00449     virtual lock_status_t           Lock() const;
00451     virtual void                    Unlock() const;
00452 
00454 
00455     // --------------------------------------------------------------
00459 
00461     virtual SString                 MimeTypeLocked() const;
00463     virtual status_t                StoreMimeTypeLocked(const SString& value);
00465     virtual size_t                  CountEntriesLocked() const;
00467     virtual ssize_t                 EntryIndexOfLocked(const SString& entry) const;
00469     virtual SString                 EntryNameAtLocked(size_t index) const;
00471     virtual status_t                StoreValueTypeAtLocked(size_t index, uint32_t type);
00473     virtual off_t                   SizeAtLocked(size_t index) const;
00475     virtual status_t                StoreSizeAtLocked(size_t index, off_t size);
00477     virtual SValue                  ValueAtLocked(size_t index) const;
00479     virtual status_t                StoreValueAtLocked(size_t index, const SValue& value);
00481     virtual void                    ReportChangeAtLocked(size_t index, const sptr<IBinder>& editor, uint32_t changes, off_t start=-1, off_t length=-1);
00482 
00484 
00488     virtual status_t                AddEntry(const SString& name, const SValue& entry);
00490     virtual status_t                RemoveEntry(const SString& name);
00492     virtual status_t                RenameEntry(const SString& entry, const SString& name);
00494     virtual sptr<INode>             CreateNode(SString* name, status_t* err);
00496     virtual sptr<IDatum>            CreateDatum(SString* name, uint32_t flags, status_t* err);
00497 
00499 
00500     // --------------------------------------------------------------
00503 
00504     virtual SString                 Reference() const;
00505 
00507 
00508             const uint32_t          m_rowID;
00509 
00510 private:
00511                                     RowNode(const RowNode&);
00512             RowNode&                operator=(const RowNode&);
00513 };
00514 
00515 // --------------------------------------------------------------------------
00516 
00518 
00523 class BSchemaTableNode::QueryIterator : public BGenericIterable::GenericIterator, public BSchemaTableNode::DataAccessor
00524 {
00525 public:
00526     // --------------------------------------------------------------
00530                                     QueryIterator(const SContext& context, const sptr<BSchemaTableNode>& owner);
00531 protected:
00532     virtual                         ~QueryIterator();
00534     virtual SValue                  Inspect(const sptr<IBinder>& caller, const SValue& which, uint32_t flags);
00535 public:
00537     virtual void                    InitAtom();
00539     virtual status_t                FinishAtom(const void* id);
00540 
00542 
00543     virtual SValue                  Options() const;
00544     virtual status_t                Remove();
00545     virtual size_t                  Count() const;
00546     virtual size_t                  Position() const;
00547     virtual void                    SetPosition(size_t p);
00548 
00549     virtual status_t                ParseArgs(const SValue& args);
00550 
00552 
00556     virtual SValue                  CreateSQLFilter(const SValue& filter) const;
00557 
00558     virtual status_t                NextLocked(uint32_t flags, SValue* key, SValue* entry);
00559 
00560 private:
00561                                     QueryIterator(const QueryIterator&);
00562             QueryIterator&          operator=(const QueryIterator&);
00563 
00564             DmOpenRef               m_ref;
00565             status_t                m_status;
00566             SValue                  m_args;
00567             SString                 m_query;
00568 
00569             uint32_t                m_cursor;
00570 };
00571 
00572 // ==========================================================================
00573 // ==========================================================================
00574 
00577 #if _SUPPORTS_NAMESPACE
00578 } } // namespace palmos::dmprovider
00579 #endif
00580 
00581 #endif // _DMPROVIDER_SCHEMATABLENODE_H