Esempio n. 1
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * interfaces
 */
tb_size_t tb_database_sqlite3_probe(tb_url_ref_t url)
{
    // check
    tb_assert_and_check_return_val(url, 0);

    // done
    tb_size_t           score = 0;
    tb_stream_ref_t  stream = tb_null;
    do
    {
        // the url arguments
        tb_char_t const* args = tb_url_args(url);
        if (args)
        {
            // find the database type
            tb_char_t const* ptype = tb_stristr(args, "type=");
            if (ptype && !tb_strnicmp(ptype + 5, "sqlite3", 7))
            {
                // ok
                score = 100;
                break;
            }
        }

        // has host or port? no sqlite3
        if (tb_url_host(url) || tb_url_port(url)) break;

        // the database path
        tb_char_t const* path = tb_url_cstr((tb_url_ref_t)url);
        tb_assert_and_check_break(path);

        // is file?
        if (tb_url_protocol(url) == TB_URL_PROTOCOL_FILE) score += 20;

        // init stream
        stream = tb_stream_init_from_url(path);
        tb_assert_and_check_break(stream);

        // open stream
        if (!tb_stream_open(stream)) break;

        // read head
        tb_char_t head[16] = {0};
        if (!tb_stream_bread(stream, (tb_byte_t*)head, 15)) break;

        // is sqlite3?
        if (!tb_stricmp(head, "SQLite format 3")) score = 100;

    } while (0);

    // exit stream
    if (stream) tb_stream_exit(stream);
    stream = tb_null;

    // trace
    tb_trace_d("probe: %s, score: %lu", tb_url_cstr((tb_url_ref_t)url), score);

    // ok?
    return score;
}
Esempio n. 2
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_database_sql_ref_t tb_database_sql_init(tb_char_t const* url)
{
    // check
    tb_assert_and_check_return_val(url, tb_null);

    // done
    tb_bool_t                   ok = tb_false;
    tb_database_sql_ref_t       database = tb_null;
    tb_url_t                    database_url;
    do
    {
        // trace
        tb_trace_d("init: %s: ..", url);

        // init url
        if (!tb_url_init(&database_url)) break;

        // make url
        if (!tb_url_cstr_set(&database_url, url)) break;

        // check protocol
        tb_size_t protocol = tb_url_protocol(&database_url);
        tb_assert_and_check_break(protocol == TB_URL_PROTOCOL_SQL || protocol == TB_URL_PROTOCOL_FILE);

        // the probe func
        static tb_size_t (*s_probe[])(tb_url_ref_t) = 
        {
            tb_null
#ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL
        ,   tb_database_mysql_probe
#endif
#ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3
        ,   tb_database_sqlite3_probe
#endif
        };

        // the init func
        static tb_database_sql_ref_t (*s_init[])(tb_url_ref_t) = 
        {
            tb_null
#ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL
        ,   tb_database_mysql_init
#endif
#ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3
        ,   tb_database_sqlite3_init
#endif
        };

        // probe the database type
        tb_size_t i = 1;
        tb_size_t n = tb_arrayn(s_probe);
        tb_size_t s = 0;
        tb_size_t m = 0;
        for (; i < n; i++)
        {
            if (s_probe[i]) 
            {
                // probe it
                tb_size_t score = s_probe[i](&database_url);
                if (score > s) 
                {
                    // save the max score
                    s = score;
                    m = i;

                    // ok?
                    if (score == 100) break;
                }
            }
        }
        tb_check_break(m < n && s_init[m]);

        // init it
        database = s_init[m](&database_url);
        tb_assert_and_check_break(database);

        // trace
        tb_trace_d("init: %s: ok", url);

        // ok
        ok = tb_true;

    } while (0);

    // exit url
    tb_url_exit(&database_url);

    // failed?
    if (!ok)
    {
        // trace
        tb_trace_d("init: %s: no", url);

        // exit database
        if (database) tb_database_sql_exit(database);
        database = tb_null;
    }

    // ok?
    return database;
}