After I posted Google Protocol Buffers Where Have You Been All My Life, I started thinking about the multiple inheritance issue a bit more. After a couple of initial trials, I believed it wasn’t going to work. I kept thinking about that, became somewhat obsessed and needed to figure out why it wasn’t going to work.
So today I started in again, and with a little bit of googling discovered that it can work. I’ve never used multiple inheritance before in any of my code, as there wasn’t a real need to. This particular bit of code I’m writing now, though, would benefit greatly from it.
As I said in my previous post, I’ve got a DatabaseRecord class. It contains functions that are common to all database accesses, including memcache storage and retrieval:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class DatabaseRecord { public: DatabaseRecord(memcached_pool_st *, SessionPool *, const char *); ~DatabaseRecord(); protected: void setTableName(const char *); int checkMemcache(std::string, std::string &); void saveValueToMemcache(std::string, std::string); int loadDataFromMemcache(std::string); virtual bool loadDataFromString(std::string) = 0; Poco::Stopwatch dbTimer; SessionPool *_dbpool; std::string fLogMsg; Logger* logger; private: std::string _tableName; memcached_pool_st *_mcpool; }; |
I then have the protocol buffer class Customer, based on this message structure:
1 2 3 4 5 6 |
message Customer { required int64 customer_id = 1; optional string name = 2; optional string contact = 3; required int32 active = 4; } |
From there, I can now create my CustomerRecord class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class CustomerRecord: public Customer, public DatabaseRecord { public: CustomerRecord(memcached_pool_st *, SessionPool *); ~CustomerRecord(); int getCustomerById(long); protected: virtual bool loadDataFromString(std::string); void saveCustomerToMemcache(); }; } |
The little bit that I was missing before was the public declarations on both of the classes it inherits from. Everything works as I had hoped it would before.
Now, when I want to extract data from a customer record, I can write code like so:
1 2 3 |
CustomerRecord cust(pool, dbpool); cust.getCustomerById(1); std::cout << "Customer name is '" << cust.name() << "'"; |
All records are cached in memcache and if its not found will automatically save the protocol buffer into memcache after it retrieves it from the database.
Its extremely fast, easy to read and easy to maintain.