--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <relation.h>
+#include <stringitem.h>
+
+char *val(void* t) {
+ static char buf[2][100];
+ static int i = 0;
+ if ( ++i >= 2 ) {
+ i = 0;
+ }
+ if ( t ) {
+ sprintf( buf[i], "\"%s\"", (char*)t );
+ return buf[i];
+ }
+ return "(null)";
+}
+
+void prtuple(char *pre, tuple *t) {
+ if ( t ) {
+ fprintf( stderr, "%s<%s, %s>\n", pre, val((*t)[0]), val((*t)[1]) );
+ } else {
+ // fprintf( stderr, "%s< >\n", pre );
+ }
+}
+
+void prdropout(const vector_index index,const void *t) {
+ prtuple( ".. ", (tuple*)t );
+}
+
+void add_relation(relation *r,char *p,char *c) {
+ tuple *t = tuple_create( 2, p, c);
+ prtuple( "Adding: ", t );
+ vector *dropped = relation_add( r, t );
+ if ( dropped ) {
+ fprintf( stderr, "Knockout %ld tuples\n", dropped->size );
+ vector_dump( dropped, prdropout );
+ vector_resize( dropped, 0, 0, 0 );
+ free( dropped );
+ }
+}
+
+typedef union {
+ struct {
+ void *c1;
+ void *c2;
+ } cols;
+ void *tup[2];
+} tuple2;
+
+int main(int argc,char **argv) {
+ relation *rltn2 = relation_create(
+ tupleschema_create(
+ 2, tuple_create( 2, (void*) &stringitem, (void*) &stringitem ) ) );
+ relation_add_constraint( rltn2, 0, 1 );
+ add_relation( rltn2, "benton", "holly" );
+ add_relation( rltn2, "benton", "molly");
+ add_relation( rltn2, "gully", "holly");
+ add_relation( rltn2, "gully", "vanitha");
+ vector_index index = 0;
+ tuple2 q1 = {{ "benton", 0 }};
+ tuple *t;
+ prtuple( "Simple query: ", &q1.tup );
+ for ( ; index < rltn2->content.table.size; index++ ) {
+ t = relation_next( rltn2, &index, &q1.tup );
+ prtuple( ".. ", t );
+ }
+ // Test null query
+ fprintf( stderr, "Null query: (null)\n" );
+ for ( index = 0 ; index < rltn2->content.table.size; index++ ) {
+ t = relation_next( rltn2, &index, 0 );
+ prtuple( ".. ", t );
+ }
+ // Test Generic query
+ q1 = (tuple2) {{ 0, 0 }};
+ prtuple( "Generic query: ", &q1.tup );
+ for ( index = 0 ; index < rltn2->content.table.size; index++ ) {
+ t = relation_next( rltn2, &index, &q1.tup );
+ prtuple( ".. ", t );
+ }
+ // Test deletion
+ q1 = (tuple2) {{ "gully", 0 }};
+ prtuple( "Deletion query: ", &q1.tup );
+ vector *deleted = relation_delete( rltn2, &q1.tup );
+ for ( index = 0 ; index < rltn2->content.table.size; index++ ) {
+ t = relation_next( rltn2, &index, 0 );
+ prtuple( ".. ", t );
+ }
+ for ( index = 0 ; index < deleted->size; index++ ) {
+ tuple **p = (tuple**) vector_next_used( deleted, &index );
+ prtuple( "** ", p? *p : 0 );
+ }
+ return 0;
+}
--- /dev/null
+/**
+ * This is a collection of tests of the relation functions.
+ */
+#include <stringitem.h>
+#include <relation.h>
+
+extern itemkeyfun tupleschema_callbacks;
+
+int main(int argc,char **argv) {
+ tuple *data[] = {
+ TUPLE( "a", "b" ),
+ TUPLE( "a", "c" ),
+ TUPLE( "a", "d" ),
+ };
+ // AxB
+ relation rel2 = RELATION( &stringitem, &stringitem );
+
+ relation_add( &rel2, data[0] );
+
+ // AxBxC
+ relation rel3 = RELATION( &stringitem, &stringitem, &stringitem );
+ // AxB -> C
+ relation_add_constraint( &rel3, 1, 1, 0 );
+ // AxC -> B
+ relation_add_constraint( &rel3, 1, 0, 1 );
+
+ return 0;
+}