株式会社エス・スリー・フォー

iPEX2.1だとコンパイル・エラーになります

そうなんですよ、iPEXはバージョン2.1でインタフェースが変更されました。

以前の版との大きな違いのひとつは、名前空間が細分化されたことです。iPEXが提供するクラスは名前空間’iPEX’に置かれていました。v2.1では名前空間’iPEX’のさらにその中に機能ごとの名前空間、たとえば’DOM’や’XSLT’を配置しています。たとえば従来のiPEX::Nodeはv2.1ではiPEX::DOM::Nodeに変更されています。

※ その他にもv2.1での変更点がかなりあります。

詳細は iPEX Version 2.1 プログラマーズガイド 8. 過去のバージョンとの互換性 を参照してください。

iPEX v2.1で実装した版を以下に示します:

/*
 * read_schema
 *
 *  by the use of:
 *    - Rogue Wave : SourcePro DB
 *    - Infoteria  : iPEX 2.1
 *
 *  build type : 'm'  -- native-StdLib / multithread / shared / release
 *               'md' -- native-StdLib / multithread / shared / debug
 */

#ifdef _MSC_VER
#pragma warning( disable: 4251 4786 )
#endif

// stdlib
#include <iostream>
#include <string>
#include <locale>

// Rogue Wave SourcePro DB
#define RW_DISABLE_DEPRECATED 
#include <rw/db/dbmgr.h>  // RWDBManager
#include <rw/db/dbase.h>  // RWDBDatabase
#include <rw/db/schema.h> // RWDBSchema
#include <rw/db/table.h>  // RWDBTable
#include <rw/db/reader.h> // RWDBReader
#include <rw/db/row.h>    // RWDBRow

// Infoteria iPEX
#include <ipexdom.h> // iPEX::DOM
#include <ipexslt.h> // iPEX::XSLT

/*
 * access-lib の設定。(ここでは MS SQL Server)
 */
#ifdef RWDEBUG
#define SERVER "msq42-md.dll"
#else
#define SERVER "msq42-m.dll"
#endif

/*
 * string conversions
 */
// UNIXの場合 L"euc-jp"
const std::wstring native = L"shift_jis";

// string(native) -> wstring(unicode)
inline std::wstring wide(const std::string& str) {
  return iPEX::Character::toWCString(str.c_str(), native);
}

// wstring(unicode) -> string(native)
inline std::string narrow(const std::wstring& str) {
  return iPEX::Character::toMBString(str.c_str(), native);
}

/*
 * ErrorHandler : reports erross/warnings
 */
class ErrorHandler : public iPEX::DOM::DOMErrorHandler {
  void report(Code code, const iPEX::DOM::Node* node, unsigned int line, const std::wstring& hint) {
    std::wcerr << getURI() << L"(" << line << L"): Error code=" 
               << code << L" hint=¥"" << hint << L"¥"" << std::endl;
  }
public:
  void fatalError(Code code, const iPEX::DOM::Node* node, unsigned int line, const std::wstring& hint)
    { report(code, node, line, hint) ; }
  void error(Code code, const iPEX::DOM::Node* node, unsigned int line, const std::wstring& hint)
    { report(code, node, line, hint) ; }
  void warning(Code code, const iPEX::DOM::Node* node, unsigned int line, const std::wstring& hint)
    { report(code, node, line, hint) ; }
};

/*
 * main routine
 */
int main(int argc, char* argv[]) {

  // iPEX初期化
  iPEX::Init init;
  iPEX::StringBufferManager sbm;

  // shift_jis/iso-2022-jp/euc-jp の各encodingをサポート
  static iPEX::CP932ConverterFactory     f_SJIS(L"shift_jis");
  static iPEX::ISO2022JPConverterFactory f_JIS(L"iso-2022-jp");
  static iPEX::EUCJPConverterFactory     f_EUC(L"euc-jp");

  // localeを'日本語'に設定
  std::locale::global(std::locale("japanese"));

  // parse-error を出力するハンドラ
  ErrorHandler error_handler;

  // argv[1]で与えられたURLに基づいて読み込み
  iPEX::Stream::InputStreamByURL in_strm(wide(argv[1]));
  iPEX::DOM::XMLReader reader(&in_strm, iPEX::DOM::Reader::NORMALIZE, &error_handler);

  // XMLをパース
  iPEX::DOM::Document* document = iPEX::DOM::IPEXDocument::createDocumentObject(sbm);
  if ( !reader.read(document) ) {
    return 1;
  }

  // ルート・エレメントを取得
  iPEX::DOM::Element* schema = document->getDocumentElement();

  // データベースに接続
  RWDBDatabase database = RWDBManager::database(SERVER,
                            narrow(schema->getAttribute(L"dsn")).c_str(),
                            narrow(schema->getAttribute(L"usr")).c_str(),
                            narrow(schema->getAttribute(L"pwd")).c_str(),
                            narrow(schema->getAttribute(L"db")).c_str());
  if ( database.isValid() ) {
    std::cerr << database.version() << std::endl;
  } else {
    std::cerr << "can't connect to a database...¥n";
    return 1;
  }

  const wchar_t* valueType [] = {
    L"NoType",       L"Char",    L"UnsignedChar",  L"Tiny",
    L"UnsignedTiny", L"Short",   L"UnsignedShort", L"Int",
    L"UnsignedInt",  L"Long",    L"UnsignedLong",  L"Float",
    L"Double",       L"Decimal", L"Date",          L"DateTime",
    L"Duration",     L"String",  L"Blob",          L"WString"
    L"MBString"
  };

  RWDBConnection connection = database.connection();

  // データベース内の全テーブルを取得
  RWDBTable  dbtables = database.dbTables(connection, RWDBDatabase::UserTable);

  // 各テーブルに対し...
  for ( RWDBReader dbreader = dbtables.reader(); dbreader(); ) {
    RWDBRow dbrow;
    dbreader >> dbrow;

    // スキーマの読み出し
    RWDBTable dbtable = database.table(dbrow[0].asString());
    dbtable.fetchSchema(connection);
    RWDBSchema dbschema = dbtable.schema();

    // <table name="テーブル名">...</table>
    iPEX::DOM::Element* table = document->createElement(L"table");
    table->setAttribute(L"name", dbrow[0].asWString().data());

    // <table> を <schema> に追加
    schema->appendChild(table);

    // スキーマの各カラムに対し...
    for ( size_t i = 0; i < dbschema.entries(); ++i ) {
      RWDBColumn dbcolumn = dbschema.column(i);
      wchar_t number[16];

      // <column name="カラム名" 属性名="属性値" ... />
      iPEX::DOM::Element* column = document->createElement(L"column"); 
      column->setAttribute(L"name", wide(dbcolumn.name().data()));

      if ( dbcolumn.type() != RWDBValue::NoType )      // type
       column->setAttribute(L"type", valueType[dbcolumn.type()]);
      if ( dbcolumn.storageLength() != RWDB_NO_TRAIT ) // size
        column->setAttribute(L"size", _itow(dbcolumn.storageLength(), number, 10));
      if ( dbcolumn.precision() != RWDB_NO_TRAIT )     // precision
        column->setAttribute(L"precision", _itow(dbcolumn.precision(), number, 10));
      if ( dbcolumn.scale() != RWDB_NO_TRAIT )         // scale
        column->setAttribute(L"scale", _itow(dbcolumn.scale(), number, 10));
      // <column> を <table> に追加
      table->appendChild(column);
    }
  }

  // 標準出力を出力先に設定
  iPEX::Stream::OutputStreamByFile out_strm(iPEX::Stream::OutputStreamByFile::STDOUT, native);

  if ( argc < 3 ) {
    // XMLをプリント
    iPEX::DOM::XMLWriter writer(&out_strm,L"",true);
    writer.write(document);
  } else {
    // XSLによるtransform   
    iPEX::Stream::InputStreamByURL in_strm(wide(argv[2]));
    iPEX::XSLT::StreamCreator creator(sbm);
    iPEX::XSLT::Processor* processor = creator.createProcessor(&in_strm);
    iPEX::XSLT::StreamResultHandler* result = iPEX::XSLT::StreamResultHandler::create(out_strm);
    processor->process(document, *result);
    delete result;
    delete processor;
  }

  delete document;

  return 0;
}