예제 #1
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * 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;
}
예제 #2
0
static tb_void_t tb_async_transfer_ostream_clos_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
{
    // check
    tb_async_transfer_impl_t* impl = (tb_async_transfer_impl_t*)priv;
    tb_assert_and_check_return(stream && impl);

    // trace
    tb_trace_d("clos: ostream: %s, state: %s", tb_url_cstr(tb_async_stream_url(stream)), tb_state_cstr(state));

    // done func
    tb_async_transfer_clos_func(impl, state);
}
예제 #3
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_void_t tb_async_stream_clos_opening(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
{
    // check
    tb_async_stream_impl_t* impl = tb_async_stream_impl(stream);
    tb_assert_and_check_return(impl);

    // trace
    tb_trace_d("clos: opening: %s, state: %s", tb_url_cstr(&impl->url), tb_state_cstr(impl->clos_opening.state));

    // closed
    tb_atomic_set(&impl->istate, TB_STATE_CLOSED);

    // done func
    if (impl->clos_opening.func) impl->clos_opening.func(stream, impl->clos_opening.state, impl->clos_opening.priv);
}
예제 #4
0
static tb_bool_t tb_async_transfer_ostream_open_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
{
    // check
    tb_async_transfer_impl_t* impl = (tb_async_transfer_impl_t*)priv;
    tb_assert_and_check_return_val(stream && impl && impl->open.func, tb_false);

    // trace
    tb_trace_d("open: ostream: %s, state: %s", tb_url_cstr(tb_async_stream_url(stream)), tb_state_cstr(state));

    // done
    tb_bool_t ok = tb_true;
    do
    {
        // ok?
        tb_check_break(state == TB_STATE_OK);

        // reset state
        state = TB_STATE_UNKNOWN_ERROR;

        // check
        tb_assert_and_check_break(impl->istream);
 
        // killed?
        if (TB_STATE_KILLING == tb_atomic_get(&impl->state))
        {
            state = TB_STATE_KILLED;
            break;
        }

        // done func
        ok = tb_async_transfer_open_func(impl, TB_STATE_OK, tb_async_stream_offset(impl->istream), tb_async_stream_size(impl->istream), impl->open.func, impl->open.priv);

        // ok
        state = TB_STATE_OK;

    } while (0);

    // failed?
    if (state != TB_STATE_OK) 
    {
        // done func
        ok = tb_async_transfer_open_func(impl, state, 0, 0, impl->open.func, impl->open.priv);
    }

    // ok
    return ok;
}
예제 #5
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
static tb_bool_t tb_database_sqlite3_open(tb_database_sql_impl_t* database)
{
    // check
    tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
    tb_assert_and_check_return_val(sqlite, tb_false);

    // done
    tb_bool_t           ok = tb_false;
    tb_char_t const*    path = tb_null;
    do
    {
        // the database path
        path = tb_url_cstr(&database->url);
        tb_assert_and_check_break(path);

        // load sqlite3 library
        if (!tb_database_sqlite3_library_load()) break;

        // open database
        if (SQLITE_OK != sqlite3_open_v2(path, &sqlite->database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, tb_null) || !sqlite->database) 
        {
            // error
            if (sqlite->database) 
            {
                // save state
                sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));

                // trace
                tb_trace_e("open: %s failed, error[%d]: %s", path, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
            }
            break;
        }

        // ok
        ok = tb_true;

    } while (0);

    // trace
    tb_trace_d("open: %s: %s", path, ok? "ok" : "no");

    // ok?
    return ok;
}
예제 #6
0
static tb_void_t tb_async_transfer_istream_clos_func(tb_async_stream_ref_t stream, tb_size_t state, tb_cpointer_t priv)
{
    // check
    tb_async_transfer_impl_t* impl = (tb_async_transfer_impl_t*)priv;
    tb_assert_and_check_return(stream && impl);

    // trace
    tb_trace_d("clos: istream: %s, state: %s", tb_url_cstr(tb_async_stream_url(stream)), tb_state_cstr(state));

    // done
    do
    {
        // ok?
        tb_check_break(state == TB_STATE_OK);

        // reset state
        state = TB_STATE_UNKNOWN_ERROR;
           
        // clos it
        if (!tb_async_stream_clos(impl->ostream, tb_async_transfer_ostream_clos_func, impl)) break;

        // ok
        state = TB_STATE_OK;

    } while (0);

    // failed?
    if (state != TB_STATE_OK) 
    {
        // trace
        tb_trace_e("clos: failed: %s", tb_state_cstr(state));

        // done func
        tb_async_transfer_clos_func(impl, state);
    }
}