Update of /cvsroot/monetdb/sql/src/storage
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv12834/src/storage

Modified Files:
      Tag: GDK-2
        Makefile.ag sql_storage.h 
Added Files:
      Tag: GDK-2
        sql_catalog.mx store.mx store_connections.mx 
        store_dependency.mx store_sequence.mx 
Log Message:
propagated changes of Monday Sep 03 2007 - Thursday Sep 06 2007
from the development trunk to the GDK-2 branch


--- NEW FILE: store.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.

@f store

@c
[...3984 lines suppressed...]

        if (tr->stime < gtrans->stime || tr->wtime || 
                        store_schema_number() != snr)
                reset_trans(tr, gtrans);
        tr = trans_init(tr, tr->stk, tr->parent);
        s->active = 1;
        s->schema = find_sql_schema(tr, s->schema_name);
        s->tr = tr;
        store_nr_active ++;
        s->status = 0;
        return psnr != tr->schema_number;
}

void
sql_trans_end(sql_session *s)
{
        s->active = 0;
        s->auto_commit = s->ac_on_commit;
        store_nr_active --;
}

Index: sql_storage.h
===================================================================
RCS file: /cvsroot/monetdb/sql/src/storage/sql_storage.h,v
retrieving revision 1.41
retrieving revision 1.41.2.1
diff -u -d -r1.41 -r1.41.2.1
--- sql_storage.h       12 Jun 2007 17:25:48 -0000      1.41
+++ sql_storage.h       6 Sep 2007 13:52:03 -0000       1.41.2.1
@@ -21,31 +21,202 @@
 
 #include "sql_catalog.h"
 
-extern list* table_select_column( sql_trans *tr, sql_column *val, sql_column 
*key, void *key_value, ...);
-extern list* table_select_column_multi_values( sql_trans *tr, sql_column *val, 
sql_column *key1 , void *key_value1, sql_column *key2,list *values);
+#define COLSIZE        1024
 
-extern ssize_t
- column_find_row(sql_trans *tr, sql_column *c, void *value, ...);
+#define isNew(x)  (x->base.flag == TR_NEW)
+#define isTemp(x) (isNew(x)||x->t->persistence!=SQL_PERSIST)
+#define isTempTable(x)   (x->persistence!=SQL_PERSIST)
+#define isGlobalTable(x) (x->persistence!=SQL_LOCAL_TEMP)
+#define isGlobalTemp(x) (x->persistence==SQL_GLOBAL_TEMP)
+#define isTempSchema(x)  (strcmp(x->base.name,"tmp") == 0)
 
-extern void *column_find_value(sql_trans *tr, sql_column *c, ssize_t rid);
+typedef enum store_type {
+       store_bat,
+       store_bpm
+} store_type;
 
-extern int
- column_update_value(sql_trans *tr, sql_column *c, ssize_t rid, void *value);
+extern sql_trans *gtrans;
+extern int store_nr_active;
 
-extern int
- table_insert(sql_trans *tr, sql_table *t, ...);
+/* relational interface */
+typedef ssize_t (*column_find_row_fptr)(sql_trans *tr, sql_column *c, void 
*value, ...);
+typedef void *(*column_find_value_fptr)(sql_trans *tr, sql_column *c, ssize_t 
rid);
+typedef int (*column_update_value_fptr)(sql_trans *tr, sql_column *c, ssize_t 
rid, void *value);
+typedef int (*table_insert_fptr)(sql_trans *tr, sql_table *t, ...);
+typedef int (*table_delete_fptr)(sql_trans *tr, sql_table *t, ssize_t rid);
 
-extern int
- table_delete(sql_trans *tr, sql_table *t, ssize_t rid);
+typedef struct rids {
+       size_t cur;
+       void *data;
+} rids;
 
-extern int
- table_dump(sql_trans *tr, sql_table *t);
+/* returns table rids, for the given select ranges */
+typedef rids *(*rids_select_fptr)( sql_trans *tr, sql_column *key, void 
*key_value_low, void *key_value_high, ...);
 
-extern int
- table_check(sql_trans *tr, sql_table *t);
+/* order rids by orderby_column values */
+typedef rids *(*rids_orderby_fptr)( sql_trans *tr, rids *r, sql_column 
*orderby_col);
+
+typedef rids *(*rids_join_fptr)( sql_trans *tr, rids *l, sql_column *lc, rids 
*r, sql_column *rc);
+
+/* return table rids from result of table_select, return (-1) when done */
+typedef ssize_t (*rids_next_fptr)(rids *r);
+
+/* clean up the resources taken by the result of table_select */
+typedef void (*rids_destroy_fptr)(rids *r);
+
+typedef struct table_functions {
+       column_find_row_fptr column_find_row;
+       column_find_value_fptr column_find_value;
+       column_update_value_fptr column_update_value;
+       table_insert_fptr table_insert;
+       table_delete_fptr table_delete;
+
+       rids_select_fptr rids_select;
+       rids_orderby_fptr rids_orderby;
+       rids_join_fptr rids_join;
+       rids_next_fptr rids_next;
+       rids_destroy_fptr rids_destroy;
+} table_functions; 
+
+extern table_functions table_funcs;
+
+/* delta table setup (ie readonly col + ins + upd + del)
+-- binds for column,idx (rdonly, inserts, updates) and delets
+*/
+typedef void *(*bind_col_fptr) (sql_trans *tr, sql_column *c, int access);
+typedef void *(*bind_idx_fptr) (sql_trans *tr, sql_idx *i, int access);
+typedef void *(*bind_del_fptr) (sql_trans *tr, sql_table *t, int access);
+
+/*
+-- append to columns and indices 
+*/
+typedef void *(*append_col_fptr) (sql_trans *tr, sql_column *c, int access, 
void *data);
+typedef void *(*append_idx_fptr) (sql_trans *tr, sql_idx *i, int access, void 
*data);
+
+/*
+-- create the necessary storage resources for columns, indices and tables
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*create_col_fptr) (sql_trans *tr, sql_column *c); 
+typedef int (*create_idx_fptr) (sql_trans *tr, sql_idx *i); 
+typedef int (*create_del_fptr) (sql_trans *tr, sql_table *t); 
+
+/*
+-- duplicate the necessary storage resources for columns, indices and tables
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*dup_col_fptr) (sql_trans *tr, sql_column *oc, sql_column *c);
+typedef int (*dup_idx_fptr) (sql_trans *tr, sql_idx *oi, sql_idx *i ); 
+typedef int (*dup_del_fptr) (sql_trans *tr, sql_table *ot, sql_table *t); 
+
+/*
+-- free the storage resources for columns, indices and tables
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*destroy_col_fptr) (sql_trans *tr, sql_column *c); 
+typedef int (*destroy_idx_fptr) (sql_trans *tr, sql_idx *i); 
+typedef int (*destroy_del_fptr) (sql_trans *tr, sql_table *t); 
+
+/*
+-- clear any storage resources for columns, indices and tables
+-- returns number of removed tuples
+*/
+typedef size_t (*clear_col_fptr) (sql_trans *tr, sql_column *c); 
+typedef size_t (*clear_idx_fptr) (sql_trans *tr, sql_idx *i); 
+typedef size_t (*clear_del_fptr) (sql_trans *tr, sql_table *t); 
+
+/*
+-- update_table rollforward the changes made from table ft to table tt 
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*update_table_fptr) (sql_trans *tr, sql_table *ft, sql_table 
*tt); 
+
+/*
+-- handle inserts and updates of columns and indices
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*col_ins_fptr) (sql_trans *tr, sql_column *c, void *data);
+typedef int (*col_upd_fptr) (sql_trans *tr, sql_column *c, void *rows, void 
*data);
+typedef int (*idx_ins_fptr) (sql_trans *tr, sql_idx *c, void *data);
+typedef int (*idx_upd_fptr) (sql_trans *tr, sql_idx *c, void *rows, void 
*data);
+/*
+-- handle deletes
+-- returns LOG_OK, LOG_ERR
+*/
+typedef int (*del_fptr) (sql_trans *tr, sql_table *c, void *rows);
+
+/* backing struct for this interface */
+typedef struct store_functions {
+
+       bind_col_fptr bind_col;
+       bind_idx_fptr bind_idx;
+       bind_del_fptr bind_del;
+
+       append_col_fptr append_col;
+       append_idx_fptr append_idx;
+
+       create_col_fptr create_col;
+       create_idx_fptr create_idx;
+       create_del_fptr create_del;
+       
+       dup_col_fptr dup_col;
+       dup_idx_fptr dup_idx;
+       dup_del_fptr dup_del;
+
+       destroy_col_fptr destroy_col;
+       destroy_idx_fptr destroy_idx;
+       destroy_del_fptr destroy_del;
+
+       clear_col_fptr clear_col;
+       clear_idx_fptr clear_idx;
+       clear_del_fptr clear_del;
+
+       update_table_fptr update_table;
+
+       col_ins_fptr col_ins;
+       col_upd_fptr col_upd;
+
+       idx_ins_fptr idx_ins;
+       idx_upd_fptr idx_upd;
+
+       del_fptr del;
+} store_functions;
+
+extern store_functions store_funcs;
+
+typedef int (*logger_create_fptr) (char *logdir, char *dbname, int 
catalog_version);
+
+typedef void (*logger_destroy_fptr) (void);
+typedef int (*logger_restart_fptr) (void);
+typedef int (*logger_cleanup_fptr) (void);
+
+typedef int (*logger_changes_fptr)(void);
+typedef int (*logger_get_sequence_fptr) (int seq, lng *id);
+
+typedef int (*log_isnew_fptr)(void);
+typedef int (*log_tstart_fptr) (void);
+typedef int (*log_tend_fptr) (void);
+typedef int (*log_sequence_fptr) (int seq, lng id);
+
+typedef struct logger_functions {
+       logger_create_fptr create;
+       logger_destroy_fptr destroy;
+       logger_restart_fptr restart;
+       logger_cleanup_fptr cleanup;
+
+       logger_changes_fptr changes;
+       logger_get_sequence_fptr get_sequence;
+
+       log_isnew_fptr log_isnew;
+       log_tstart_fptr log_tstart;
+       log_tend_fptr log_tend;
+       log_sequence_fptr log_sequence;
+} logger_functions;
+
+extern logger_functions logger_funcs;
 
 extern int
- store_init(int debug, char *logdir, char *dbname, backend_stack stk);
+ store_init(int debug, store_type store, char *logdir, char *dbname, 
backend_stack stk);
 extern void
  store_exit(void);
 

--- NEW FILE: store_sequence.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.

@f store_sequence
@h
#ifndef STORE_SEQ_H
#define STORE_SEQ_H

#include "sql_catalog.h"

extern void sequences_init(void);
extern void sequences_exit(void);

extern int seq_next_value(sql_sequence *seq, lng *val);

/* for bulk next values, the API is split in 3 parts */

typedef struct seqbulk {
        void *internal_seq;
        sql_sequence *seq;
        int cnt;
        int save; 
} seqbulk;

extern seqbulk *seqbulk_create(sql_sequence *seq, int cnt);
extern int seqbulk_next_value(seqbulk *seq, lng *val);
extern void seqbulk_destroy(seqbulk *seq);

extern int seq_get_value(sql_sequence *seq, lng *val);
extern int seq_restart(sql_sequence *seq, lng start);

#endif /* STORE_SEQ_H */
@c
#include "sql_config.h"
#include "store_sequence.h"
#include "sql_storage.h"
#include <gdk_logger.h>

typedef struct store_sequence {
        sqlid seqid;
        bit called;
        lng cur;
        lng cached;
} store_sequence;

static list *sql_seqs = NULL;

static void 
sequence_destroy( store_sequence *s )
{
        _DELETE(s);
}

void sequences_init(void)
{
        sql_seqs = list_create( (fdestroy)sequence_destroy );
}

void sequences_exit(void)
{
        list_destroy(sql_seqs);
}

/* lock is held */
static void 
sql_update_sequence_cache(sql_sequence *seq, lng cached) 
{
        logger_funcs.log_sequence(seq->base.id, cached);
}

/* lock is held */
static store_sequence *
sql_create_sequence(sql_sequence *seq ) 
{
        lng id = 0;
        store_sequence *s = NULL;

        s = NEW(store_sequence);
        s -> seqid = seq->base.id;
        s -> called = 0;
        s -> cur = seq->start;    
        s -> cached = seq->start;

        if (seq->base.flag == TR_OLD && 
            logger_funcs.get_sequence(seq->base.id, &id )) 
                s->cached = id;
        s -> cur = s->cached;
        return s;
}

int seq_restart(sql_sequence *seq, lng start)
{
        node *n = NULL;
        store_sequence *s;

        store_lock();
        for ( n = sql_seqs->h; n; n = n ->next ) {
                s = n->data;
                if (s->seqid == seq->base.id)
                        break;
        }
        if (!n) {
                s = sql_create_sequence(seq);
                if (!s) {
                        store_unlock();
                        return 0;
                }
                list_append(sql_seqs, s);
        } else {
                s = n->data;
        }
        s->called = 0;
        s->cur = start;
        s->cached = start;
        /* handle min/max and cycle */
        if ((seq->maxvalue && s->cur > seq->maxvalue) ||
            (seq->minvalue && s->cur < seq->minvalue))
        {
                /* we're out of numbers */
                store_unlock();
                return(0);
        }
        sql_update_sequence_cache(seq, s->cached);
        store_unlock(); 
        return 1;
}


int
seq_next_value(sql_sequence *seq, lng *val)
{
        lng nr = 0;
        node *n = NULL;
        store_sequence *s;
        int save = 0;

        *val = 0;
        store_lock();
        for ( n = sql_seqs->h; n; n = n ->next ) {
                s = n->data;
                if (s->seqid == seq->base.id)
                        break;
        }
        if (!n) {
                s = sql_create_sequence(seq);
                if (!s) {
                        store_unlock();
                        return 0;
                }
                list_append(sql_seqs, s);
        } else {
                s = n->data;
                if (s->called)
                        s->cur += seq->increment;
        }
        /* handle min/max and cycle */
        if ((seq->maxvalue && s->cur > seq->maxvalue) ||
            (seq->minvalue && s->cur < seq->minvalue))
        {
                if (seq->cycle) {
                        /* cycle to the min value again */
                        s->cur = seq->minvalue;
                        save = 1;
                } else { /* we're out of numbers */
                        store_unlock();
                        return(0);
                }
        }
        s->called = 1;
        nr = s->cur;
        *val = nr;
        if (save || nr == s->cached) {
                s->cached = nr + seq->cacheinc*seq->increment;
                sql_update_sequence_cache(seq, s->cached);
                store_unlock(); 
                return 1;
        }
        assert(nr<s->cached);
        store_unlock(); 
        return 1;
}

seqbulk *seqbulk_create(sql_sequence *seq, int cnt)
{
        seqbulk *sb = NEW(seqbulk);
        store_sequence *s;
        node *n = NULL;

        if (!sb)
                return NULL;

        store_lock();
        sb->seq = seq;
        sb->cnt = cnt;
        sb->save = 0;

        for ( n = sql_seqs->h; n; n = n ->next ) {
                s = n->data;
                if (s->seqid == seq->base.id)
                        break;
        }
        if (!n) {
                s = sql_create_sequence(seq);
                if (!s) {
                        _DELETE(sb);
                        return NULL;
                }
                list_append(sql_seqs, s);
        } else {
                s = n->data;
        }
        sb->internal_seq = s;
        return sb;
}

void seqbulk_destroy(seqbulk *sb)
{

        if (sb->save) {
                sql_sequence *seq = sb->seq;
                store_sequence *s = sb->internal_seq;

                sql_update_sequence_cache(seq, s->cached);
        }
        _DELETE(sb);
        store_unlock();
}

int seqbulk_next_value(seqbulk *sb, lng *val)
{
        lng nr = 0;
        store_sequence *s = sb->internal_seq;
        sql_sequence *seq = sb->seq;

        if (s->called)
                s->cur += seq->increment;

        /* handle min/max and cycle */
        if ((seq->maxvalue && s->cur > seq->maxvalue) ||
            (seq->minvalue && s->cur < seq->minvalue))
        {
                if (seq->cycle) {
                        /* cycle to the min value again */
                        s->cur = seq->minvalue;
                        sb->save = 1;
                } else { /* we're out of numbers */
                        return(0);
                }
        }
        s->called = 1;
        nr = s->cur;
        *val = nr;
        if (nr == s->cached) {
                s->cached = nr + seq->cacheinc*seq->increment;
                sb->save = 1;
                return 1;
        }
        assert(nr<s->cached);
        return 1;
}

int
seq_get_value(sql_sequence *seq, lng *val)
{
        node *n = NULL;
        store_sequence *s;

        *val = 0;
        store_lock();
        for ( n = sql_seqs->h; n; n = n ->next ) {
                s = n->data;
                if (s->seqid == seq->base.id)
                        break;
        }
        if (!n) {
                s = sql_create_sequence(seq);
                if (!s) {
                        store_unlock();
                        return 0;
                }
                list_append(sql_seqs, s);
        } else {
                s = n->data;
        }
        *val = s->cur;
        if (s->called)
                *val += seq->increment;
        /* handle min/max and cycle */
        if ((seq->maxvalue && *val > seq->maxvalue) ||
            (seq->minvalue && *val < seq->minvalue))
        {
                if (seq->cycle) {
                        /* cycle to the min value again */
                        *val = seq->minvalue;
                } else { /* we're out of numbers */
                        store_unlock();
                        return(0);
                }
        }
        store_unlock();
        return 1;
}

--- NEW FILE: store_connections.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.

@f store_connections
@a R.A. Goncalves

@h
#ifndef STORE_CONNECTIONS_H
#define STORE_CONNECTIONS_H

#include "store_dependency.h"

#endif /*STORE_DEPEND_H */
@c

#include "sql_config.h"
#include "store_connections.h"



/*Function to create a connection*/
int
sql_trans_connect_catalog(sql_trans* tr, char *server, int port, char *db, char 
*db_alias, char *user, char *passwd, char *lang)
{
        int id = store_next_oid(), port_l = port;
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table *t = find_sql_table(s, "connections");
        sql_column *c_server = find_sql_column(t, "server");
        sql_column *c_db = find_sql_column(t, "db");
        sql_column *c_db_alias = find_sql_column(t, "db_alias");

        if ((table_funcs.column_find_row(tr, c_server, server, c_db, db, NULL) 
== -1) && (table_funcs.column_find_row(tr, c_db_alias, db_alias, NULL) == -1)) {
                table_funcs.table_insert(tr, t, &id, server, &port_l, db, 
db_alias, user, passwd, lang);
                return id;
        }
        
        return 0;
}

/*Function to drop the connection*/
int
sql_trans_disconnect_catalog(sql_trans* tr, char * db_alias)
{
        ssize_t rid = -1;
        int id = 0;
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table* t = find_sql_table(s, "connections");

        sql_column * col_db_alias = find_sql_column(t, "db_alias");
        sql_column * col_id = find_sql_column(t, "id");

        rid = table_funcs.column_find_row(tr, col_db_alias, db_alias, NULL);
        if (rid != -1) {
                id = *(int *) table_funcs.column_find_value(tr, col_id, rid);
                table_funcs.table_delete(tr, t, rid);
        }
        else 
                id = 0;

        return id;
}

int
sql_trans_disconnect_catalog_ALL(sql_trans* tr)
{
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table* t = find_sql_table(s, "connections");

        sql_trans_clear_table(tr, t);

        return 1;
}

list*
sql_trans_get_connection(sql_trans* tr, int id, char *server, char *db, char 
*db_alias, char *user)
{
        ssize_t rid = -1;
        sql_schema *s = find_sql_schema(tr, "sys");     
        sql_table *con = find_sql_table(s, "connections");
        list *con_arg_list = list_create((fdestroy) NULL); 
        sql_column *col_id, *col_server, *col_db, *col_db_alias, *col_user, 
*col_port, *col_passwd, *col_lang;
        char dbalias[BUFSIZ];

        col_id = find_sql_column(con, "id");
        col_db_alias = find_sql_column(con, "db_alias");
        col_server = find_sql_column(con, "server");
        col_db = find_sql_column(con, "db");
        col_user = find_sql_column(con, "user");
        col_port = find_sql_column(con, "port");
        col_passwd = find_sql_column(con, "password");
        col_lang = find_sql_column(con, "language");
        
        if (db_alias == NULL){
                snprintf(dbalias, BUFSIZ, "%s_%s_%s", server, db, user);
                db_alias = dbalias;
        }

        if (id != -1)
                rid = table_funcs.column_find_row(tr, col_id, &id, NULL);
        else    
                rid = table_funcs.column_find_row(tr, col_db_alias, db_alias, 
NULL);

        if (rid != -1) {
                list_append(con_arg_list, (int *) 
table_funcs.column_find_value(tr, col_id, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_server, rid));
                list_append(con_arg_list, (int *) 
table_funcs.column_find_value(tr, col_port, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_db, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_db_alias, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_user, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_passwd, rid));
                list_append(con_arg_list, (char *) 
table_funcs.column_find_value(tr, col_lang, rid));
        }

        return con_arg_list;
}

--- NEW FILE: store_dependency.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.

@f store_dependency
@a R.A. Goncalves

@h
#ifndef STORE_DEPEND_H
#define STORE_DEPEND_H

#include "sql_types.h"
#include "sql_backend.h"
#include "store_sequence.h"

#endif /*STORE_DEPEND_H */
@c

#include "sql_config.h"
#include "store_dependency.h"

static int
list_find_func_id(list *ids, int id) {
        node *n = ids->h;
        while(n) {
                sql_func * f = n->data;
                if (f->base.id == id)
                        return id;
                else 
                        n = n->next;
        }
        return 0;
}

/*Function to create a dependency*/
void
sql_trans_create_dependency(sql_trans* tr, sqlid id, sqlid depend_id, short 
depend_type)
{
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table *t = find_sql_table(s, "dependencies");
        sql_column *c_id = find_sql_column(t, "id");
        sql_column *c_dep_id = find_sql_column(t, "depend_id");
        sql_column *c_dep_type = find_sql_column(t, "depend_type");

        if (table_funcs.column_find_row(tr, c_id, &id, c_dep_id, &depend_id, 
c_dep_type, &depend_type, NULL) == -1)
                table_funcs.table_insert(tr, t, &id, &depend_id, &depend_type);
}

/*Function to drop the dependencies on depend_id*/
void
sql_trans_drop_dependencies(sql_trans* tr, sqlid depend_id)
{
        ssize_t rid;
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table* deps = find_sql_table(s, "dependencies");
        sql_column * dep_dep_id = find_sql_column(deps, "depend_id");
        rids *rs;
        
        rs = table_funcs.rids_select(tr, dep_dep_id, &depend_id, &depend_id, 
NULL);
        for(rid = table_funcs.rids_next(rs); rid>=0; rid = 
table_funcs.rids_next(rs)) 
                table_funcs.table_delete(tr, deps, rid);
        table_funcs.rids_destroy(rs);
}

/*It returns a list with depend_id_1, depend_type_1, depend_id_2, 
depend_type_2, ....*/
list*
sql_trans_get_dependencies(sql_trans* tr, int id, short depend_type, list * 
ignore_ids)
{
        void *v;
        sql_schema *s = find_sql_schema(tr, "sys");     
        sql_table *deps = find_sql_table(s, "dependencies");
        sql_column *dep_id, *dep_dep_id, *dep_dep_type, *tri_id, *table_id;
        list *dep_list = list_create((fdestroy) GDKfree); 
        ssize_t r;
        rids *rs;

        dep_id = find_sql_column(deps, "id");
        dep_dep_id = find_sql_column(deps, "depend_id");
        dep_dep_type = find_sql_column(deps, "depend_type");

        rs = table_funcs.rids_select(tr, dep_id, &id, &id, NULL);
        for(r = table_funcs.rids_next(rs); r>=0; r = table_funcs.rids_next(rs)){
                v = table_funcs.column_find_value(tr, dep_dep_id, r);
                id = *(sqlid*)v;                
                if (!(ignore_ids  && list_find_func_id(ignore_ids, id))) {
                        list_append(dep_list, v);
                        v = table_funcs.column_find_value(tr, dep_dep_type, r);
                        list_append(dep_list, v);
                } else {
                        _DELETE(v);
                }
        }
        table_funcs.rids_destroy(rs);

        if (depend_type == TABLE_DEPENDENCY) {
                sql_table *triggers = find_sql_table(s, "triggers");
                table_id = find_sql_column(triggers, "table_id");
                tri_id = find_sql_column(triggers, "id");
                depend_type = TRIGGER_DEPENDENCY;

                rs = table_funcs.rids_select(tr, table_id, &id, &id, NULL);
                for(r = table_funcs.rids_next(rs); r>=0; r = 
table_funcs.rids_next(rs)) {
                        v = table_funcs.column_find_value(tr, tri_id, r);
                        list_append(dep_list, v);
                        v = NEW(sht);
                        *(sht*)v = depend_type;
                        list_append(dep_list, v);
                }
                table_funcs.rids_destroy(rs);
        }
        return dep_list;
}

/*It checks if there are dependency between two ID's */
int
sql_trans_get_dependency_type(sql_trans *tr, int id, short depend_type)
{
        ssize_t rid;
        sql_schema *s;
        sql_table *dep;
        sql_column *dep_id, *dep_dep_id, *dep_dep_type;

        s = find_sql_schema(tr, "sys"); 

        dep = find_sql_table(s, "dependencies");

        dep_id = find_sql_column(dep, "id");
        dep_dep_id = find_sql_column(dep, "depend_id");
        dep_dep_type = find_sql_column(dep, "depend_type");

        rid = table_funcs.column_find_row(tr, dep_id, &id, dep_dep_type, 
&depend_type, NULL);
        if (rid != -1)  
                return *(int *) table_funcs.column_find_value(tr, dep_dep_id, 
rid);
        else return -1;
}

/*It checks if there are dependency between two ID's */
int
sql_trans_check_dependency(sql_trans *tr, int id, int depend_id, short 
depend_type)
{
        ssize_t rid;
        sql_schema *s;
        sql_table *dep;
        sql_column *dep_id, *dep_dep_id, *dep_dep_type;

        s = find_sql_schema(tr, "sys"); 

        dep = find_sql_table(s, "dependencies");

        dep_id = find_sql_column(dep, "id");
        dep_dep_id = find_sql_column(dep, "depend_id");
        dep_dep_type = find_sql_column(dep, "depend_type");

        rid = table_funcs.column_find_row(tr, dep_id, &id, dep_dep_id, 
&depend_id, dep_dep_type, &depend_type, NULL);
        if (rid != -1)  
                return 1;
        else return 0;
}



/*Schema on users*/

list *
sql_trans_schema_user_dependencies(sql_trans *tr, int schema_id)
{
        void *v;
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table *auths = find_sql_table(s, "auths");
        sql_column *auth_id = find_sql_column(auths, "id");
        short type = USER_DEPENDENCY;
        list *l = list_create((fdestroy) GDKfree);
        rids *users = backend_schema_user_dependencies(tr, schema_id);
        ssize_t rid;
        
        for(rid = table_funcs.rids_next(users); rid>=0; rid = 
table_funcs.rids_next(users)) {
                v = table_funcs.column_find_value(tr, auth_id, rid);
                list_append(l,v);
                v = NEW(sht);
                *(sht*)v = type;
                list_append(l,v);
        }
        table_funcs.rids_destroy(users);
        return l;
}

/*owner on schemas*/
list *
sql_trans_owner_schema_dependencies(sql_trans *tr, int owner_id)
{
        void *v;
        sql_schema * s = find_sql_schema(tr, "sys");
        sql_table *schemas = find_sql_table(s, "schemas");
        sql_column *schema_owner = find_sql_column(schemas, "owner");
        sql_column *schema_id = find_sql_column(schemas, "id");
        short type = SCHEMA_DEPENDENCY;
        list *l = list_create((fdestroy) GDKfree);
        rids *rs = table_funcs.rids_select(tr, schema_owner, &owner_id, 
&owner_id, NULL);
        ssize_t rid;
        
        for(rid = table_funcs.rids_next(rs); rid>=0; rid = 
table_funcs.rids_next(rs)) {
                v = table_funcs.column_find_value(tr, schema_id, rid);
                list_append(l, v);
                v = NEW(sht);
                *(sht*)v = type;
                list_append(l,v);
        }
        table_funcs.rids_destroy(rs);
        return l;
}

/*Function on Functions*/




Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/sql/src/storage/Makefile.ag,v
retrieving revision 1.8
retrieving revision 1.8.6.1
diff -u -d -r1.8 -r1.8.6.1
--- Makefile.ag 3 Jan 2007 12:39:49 -0000       1.8
+++ Makefile.ag 6 Sep 2007 13:52:02 -0000       1.8.6.1
@@ -21,3 +21,13 @@
 EXTRA_DIST = sql_storage.h
 
 SUBDIRS = bat
+
+INCLUDES = ../include ../common $(MONETDB_INCS)
+
+lib_store = {
+       NOINST
+       DIR = libdir
+       SOURCES = \
+               store_dependency.mx store_connections.mx store_sequence.mx \
+               store.mx sql_catalog.mx 
+}

--- NEW FILE: sql_catalog.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.

@f sql_catalog
@c
#include "sql_config.h"
#include "sql_catalog.h"

node *
cs_find_name(changeset * cs, char *name)
{
        return list_find_name(cs->set, name);
}

node *
list_find_name(list *l, char *name)
{
        node *n;

        if (l)
                for (n = l->h; n; n = n->next) {
                        sql_base *b = n->data;

                        /* check if names match */
                        if (name[0] == b->name[0] && strcmp(name, b->name) == 
0) {
                                return n;
                        }
                }
        return NULL;
}

node *
cs_find_id(changeset * cs, int id)
{
        node *n;
        list *l = cs->set;

        if (l)
                for (n = l->h; n; n = n->next) {
                        sql_base *b = n->data;

                        /* check if names match */
                        if (b->id == id) {
                                return n;
                        }
                }
        return NULL;
}

node *
list_find_id(list *l, int id)
{
        node *n;

        if (l)
                for (n = l->h; n; n = n->next) {

                        /* check if ids match */
                        if (id == *(int *) n->data) {
                                return n;
                        }
                }
        return NULL;
}

node *
list_find_base_id(list *l, int id)
{
        node *n;

        if (l)
                for (n = l->h; n; n = n->next) {
                        sql_base *b = n->data;

                        /* check if names match */
                        if (id == b->id) {
                                return n;
                        }
                }
        return NULL;
}


node *
find_sql_key_node(sql_table *t, char *kname, int id)
{
        if (kname)
                return cs_find_name(&t->keys, kname);
        else
                return cs_find_id(&t->keys, id);
}

sql_key *
find_sql_key(sql_table *t, char *kname)
{
        node *n = find_sql_key_node(t, kname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sql_idx_node(sql_table *t, char *kname, int id)
{
        if (kname)
                return cs_find_name(&t->idxs, kname);
        else
                return cs_find_id(&t->idxs, id);
}

sql_idx *
find_sql_idx(sql_table *t, char *kname)
{
        node *n = find_sql_idx_node(t, kname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sql_column_node(sql_table *t, char *cname, int id)
{
        if (cname)
                return cs_find_name(&t->columns, cname);
        else
                return cs_find_id(&t->columns, id);
}

sql_column *
find_sql_column(sql_table *t, char *cname)
{
        node *n = find_sql_column_node(t, cname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sql_table_node(sql_schema *s, char *tname, int id)
{
        if (tname)
                return cs_find_name(&s->tables, tname);
        else
                return cs_find_id(&s->tables, id);
}

sql_table *
find_sql_table(sql_schema *s, char *tname)
{
        node *n = find_sql_table_node(s, tname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sql_sequence_node(sql_schema *s, char *sname, int id)
{
        if (sname)
                return cs_find_name(&s->seqs, sname);
        else
                return cs_find_id(&s->seqs, id);
}

sql_sequence *
find_sql_sequence(sql_schema *s, char *sname)
{
        node *n = find_sql_sequence_node(s, sname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sql_schema_node(sql_trans *t, char *sname, int id)
{
        if (sname)
                return cs_find_name(&t->schemas, sname);
        else
                return cs_find_id(&t->schemas, id);
}

sql_schema *
find_sql_schema(sql_trans *t, char *sname)
{
        node *n = find_sql_schema_node(t, sname, -1);

        if (n)
                return n->data;
        return NULL;
}

node *
find_sqlname(list *l, char *name)
{
        if (l) {
                node *n;

                for (n = l->h; n; n = n->next) {
                        sql_type *t = n->data;

                        if (strcmp(t->sqlname, name) == 0)
                                return n;
                } 
        }
        return NULL;
}

node *
find_sql_type_node(sql_schema * s, char *tname, int id)
{
        if (tname)
                return find_sqlname(s->types.set, tname);
        else 
                return cs_find_id(&s->types, id);
}

sql_type *
find_sql_type(sql_schema * s, char *tname)
{
        node *n = find_sql_type_node(s, tname, -1);

        if (n)
                return n->data;
        return NULL;
}

sql_type *
sql_trans_bind_type(sql_trans *tr, sql_schema *c, char *name)
{
        node *n;
        sql_type *t = NULL;

        if (tr->schemas.set)
                for (n = tr->schemas.set->h; n && !t; n = n->next) {
                        sql_schema *s = n->data;

                        t = find_sql_type(s, name);
                }

        if (!t && c)
                t = find_sql_type(c, name);

        if (!t)
                return NULL;
        /* t->base.rtime = tr->rtime; */
        return t;
}

node *
find_sql_func_node(sql_schema * s, char *tname, int id)
{
        if (tname)
                return cs_find_name(&s->funcs, tname);
        else
                return cs_find_id(&s->funcs, id);
}

sql_func *
find_sql_func(sql_schema * s, char *tname)
{
        node *n = find_sql_func_node(s, tname, -1);

        if (n)
                return n->data;
        return NULL;
}

list *
find_all_sql_func(sql_schema * s, char *name, int is_func)
{
        list *l = s->funcs.set, *res = NULL;
        node *n = NULL;

        if (l)
                for (n = l->h; n; n = n->next) {
                        sql_base *b = n->data;
                        sql_func *f = n->data;

                        /* check if names match */
                        if (f->is_func == is_func && name[0] == b->name[0] && 
strcmp(name, b->name) == 0) {
                                if (!res)
                                        res = list_create((fdestroy) NULL);
                                list_append(res, n->data);
                        }
                }
        return res;
}

sql_func *
sql_trans_bind_func(sql_trans *tr, char *name)
{
        node *n;
        sql_func *t = NULL;

        if (tr->schemas.set)
                for (n = tr->schemas.set->h; n && !t; n = n->next) {
                        sql_schema *s = n->data;

                        t = find_sql_func(s, name);
                }
        if (!t)
                return NULL;
        /*
           t->base.rtime = tr->rtime;
         */

        return t;
}


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins

Reply via email to