void test_a_db_with_a_connection_with_tables::can_update_blob_attribute_bound_value() { // insert new object DB::Statement statement = connection->prepare( "insert into object default values"); CPPUNIT_ASSERT(statement.isValid()); CPPUNIT_ASSERT(connection->execute(statement)); long long object_id = connection->lastInsertRowId(); CPPUNIT_ASSERT(object_id != 0); // insert blob attribute statement = connection->prepare( "insert into attribute_blob (value,type,object_id) values (X'012345',%d,%lld)", 1236, object_id); CPPUNIT_ASSERT(statement.isValid()); CPPUNIT_ASSERT(connection->execute(statement)); // prepare update blob attribute statement statement = connection->prepare( "update attribute_blob set value=? where type=%d and object_id=%lld", 1236, object_id); CPPUNIT_ASSERT(statement.isValid()); // bind blob (with embedded zero!) to the parameter const char data[] = {10,11,0,12,13,14,15,16}; std::string msg(data,sizeof(data)); CPPUNIT_ASSERT(DB::Bindings(statement).bindBlob(1,msg.data(),msg.size(),NULL)); // update the blob value of the attribute CPPUNIT_ASSERT(connection->execute(statement)); // retrieve the blob value from the attribute statement = connection->prepare( "select value from attribute_blob as t where t.type=%d and t.object_id=%lld", 1236, object_id); CPPUNIT_ASSERT(statement.isValid()); DB::Result result = connection->perform(statement); CPPUNIT_ASSERT(result.isValid()); // check that the retrieved blob value matches the original data. CPPUNIT_ASSERT_EQUAL(result.getFieldLength(1), sizeof(data)); std::string msgstored((const char *)result.getBinary(1),result.getFieldLength(1)); CPPUNIT_ASSERT_EQUAL(msg, msgstored); }
OSAttribute *DBObject::accessAttribute(CK_ATTRIBUTE_TYPE type) { switch (attributeKind(type)) { case akUnknown: return NULL; case akBoolean: { // try to find the attribute in the boolean attribute table DB::Statement statement = _connection->prepare( "select value from attribute_boolean where type=%lu and object_id=%lld", type, _objectId); if (!statement.isValid()) { return NULL; } DB::Result result = _connection->perform(statement); if (!result.isValid()) { return NULL; } // Store the attribute in the transaction when it is active. std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes; if (_transaction) attrs = _transaction; bool value = result.getInt(1) != 0; std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it = attrs->find(type); OSAttribute *attr; if (it != attrs->end()) { if (it->second != NULL) { delete it->second; } it->second = new OSAttribute(value); attr = it->second; } else { attr = new OSAttribute(value); (*attrs)[type] = attr; } return attr; } case akInteger: { // try to find the attribute in the integer attribute table DB::Statement statement = _connection->prepare( "select value from attribute_integer where type=%lu and object_id=%lld", type, _objectId); if (!statement.isValid()) { return NULL; } DB::Result result = _connection->perform(statement); if (!result.isValid()) { return NULL; } // Store the attribute in the transaction when it is active. std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes; if (_transaction) attrs = _transaction; unsigned long value = result.getULongLong(1); std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it = attrs->find(type); OSAttribute *attr; if (it != attrs->end()) { if (it->second != NULL) { delete it->second; } it->second = new OSAttribute(value); attr = it->second; } else { attr = new OSAttribute(value); (*attrs)[type] = attr; } return attr; } case akBinary: { // try to find the attribute in the binary attribute table DB::Statement statement = _connection->prepare( "select value from attribute_binary where type=%lu and object_id=%lld", type, _objectId); if (!statement.isValid()) { return NULL; } DB::Result result = _connection->perform(statement); if (!result.isValid()) { return NULL; } // Store the attribute in the transaction when it is active. std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes; if (_transaction) attrs = _transaction; const unsigned char *value = result.getBinary(1); size_t size = result.getFieldLength(1); std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it = attrs->find(type); OSAttribute *attr; if (it != attrs->end()) { if (it->second != NULL) { delete it->second; } it->second = new OSAttribute(ByteString(value,size)); attr = it->second; } else { attr = new OSAttribute(ByteString(value,size)); (*attrs)[type] = attr; return attr; } return attr; } case akMechSet: { // try to find the attribute in the binary attribute table DB::Statement statement = _connection->prepare( "select value from attribute_binary where type=%lu and object_id=%lld", type, _objectId); if (!statement.isValid()) { return NULL; } DB::Result result = _connection->perform(statement); if (!result.isValid()) { return NULL; } // Store the attribute in the transaction when it is active. std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes; if (_transaction) attrs = _transaction; const unsigned char *value = result.getBinary(1); size_t size = result.getFieldLength(1); std::set<CK_MECHANISM_TYPE> set; if (!decodeMechanismTypeSet(set, value, size)) { return NULL; } OSAttribute *attr; std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it = attrs->find(type); if (it != attrs->end()) { if (it->second != NULL) { delete it->second; } it->second = new OSAttribute(set); attr = it->second; } else { attr = new OSAttribute(set); (*attrs)[type] = attr; return attr; } return attr; } case akAttrMap: { // try to find the attribute in the array attribute table DB::Statement statement = _connection->prepare( "select value from attribute_array where type=%lu and object_id=%lld", type, _objectId); if (!statement.isValid()) { return NULL; } DB::Result result = _connection->perform(statement); if (!result.isValid()) { return NULL; } // Store the attribute in the transaction when it is active. std::map<CK_ATTRIBUTE_TYPE,OSAttribute*> *attrs = &_attributes; if (_transaction) attrs = _transaction; const unsigned char *binary = result.getBinary(1); size_t size = result.getFieldLength(1); std::map<CK_ATTRIBUTE_TYPE,OSAttribute*>::iterator it = attrs->find(type); OSAttribute *attr; if (it != attrs->end()) { std::map<CK_ATTRIBUTE_TYPE,OSAttribute> value; if (!decodeAttributeMap(value,binary,size)) { return NULL; } if (it->second != NULL) { delete it->second; } it->second = new OSAttribute(value); attr = it->second; } else { std::map<CK_ATTRIBUTE_TYPE,OSAttribute> value; if (!decodeAttributeMap(value,binary,size)) { return NULL; } attr = new OSAttribute(value); (*attrs)[type] = attr; return attr; } return attr; } } return NULL; }