lib: add monitor_cond_change API to C IDL lib
[cascardo/ovs.git] / ovsdb / ovsdb-idlc.in
index 0d836c0..253344e 100755 (executable)
@@ -229,11 +229,38 @@ bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id);
 
         print
         for columnName, column in sorted(table.columns.iteritems()):
-             if column.type.is_map():
+            if column.type.is_map():
                 print 'void %(s)s_update_%(c)s_setkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName},
                 print '%(coltype)s, %(valtype)s);' % {'coltype':column.type.key.toCType(prefix), 'valtype':column.type.value.toCType(prefix)}
                 print 'void %(s)s_update_%(c)s_delkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName},
-                print '%(coltype)s);' % {'coltype':column.type.key.toCType(prefix)}
+                print '%(coltype)s);' % {'coltype':column.type.key.toCType(prefix)},
+
+            print 'void %(s)s_add_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function,' % {'s': structName, 'c': columnName},
+            if column.type.is_smap():
+                args = ['const struct smap *']
+            else:
+                comment, members = cMembers(prefix, tableName, columnName,
+                                            column, True)
+                args = ['%(type)s%(name)s' % member for member in members]
+            print '%s);' % ', '.join(args)
+
+        print 'void %s_add_clause_true(struct ovsdb_idl *idl);' % structName
+        print 'void %s_add_clause_false(struct ovsdb_idl *idl);' % structName
+
+        print
+        for columnName, column in sorted(table.columns.iteritems()):
+            print 'void %(s)s_remove_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function,' % {'s': structName, 'c': columnName},
+            if column.type.is_smap():
+                args = ['const struct smap *']
+            else:
+                comment, members = cMembers(prefix, tableName, columnName,
+                                            column, True)
+                args = ['%(type)s%(name)s' % member for member in members]
+            print '%s);' % ', '.join(args)
+
+        print 'void %s_remove_clause_true(struct ovsdb_idl *idl);' % structName
+        print 'void %s_remove_clause_false(struct ovsdb_idl *idl);' % structName
+
         print
 
     # Table indexes.
@@ -828,6 +855,339 @@ void
         'C': columnName.upper()}
         # End Update/Delete of partial maps
 
+        # Add clause functions.
+        for columnName, column in sorted(table.columns.iteritems()):
+            type = column.type
+
+            comment, members = cMembers(prefix, tableName, columnName,
+                                        column, True)
+
+            if type.is_smap():
+                print comment
+                print """void
+%(s)s_add_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function, const struct smap *%(c)s)
+{
+    struct ovsdb_datum datum;
+
+    ovs_assert(inited);
+    if (%(c)s) {
+        struct smap_node *node;
+        size_t i;
+
+        datum.n = smap_count(%(c)s);
+        datum.keys = xmalloc(datum.n * sizeof *datum.keys);
+        datum.values = xmalloc(datum.n * sizeof *datum.values);
+
+        i = 0;
+        SMAP_FOR_EACH (node, %(c)s) {
+            datum.keys[i].string = xstrdup(node->key);
+            datum.values[i].string = xstrdup(node->value);
+            i++;
+        }
+        ovsdb_datum_sort_unique(&datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
+    } else {
+        ovsdb_datum_init_empty(&datum);
+    }
+
+    ovsdb_idl_condition_add_clause(idl,
+                                   &%(p)stable_classes[%(P)sTABLE_%(T)s],
+                                   function,
+                                   &%(s)s_columns[%(S)s_COL_%(C)s],
+                                   &datum);
+}
+""" % {'t': tableName,
+       'T': tableName.upper(),
+       'p': prefix,
+       'P': prefix.upper(),
+       's': structName,
+       'S': structName.upper(),
+       'c': columnName,
+       'C': columnName.upper()}
+                continue
+
+            keyVar = members[0]['name']
+            nVar = None
+            valueVar = None
+            if type.value:
+                valueVar = members[1]['name']
+                if len(members) > 2:
+                    nVar = members[2]['name']
+            else:
+                if len(members) > 1:
+                    nVar = members[1]['name']
+
+            print comment
+            print 'void'
+            print '%(s)s_add_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function, %(args)s)' % \
+                {'s': structName, 'c': columnName,
+                 'args': ', '.join(['%(type)s%(name)s' % m for m in members])}
+            print "{"
+            print "    struct ovsdb_datum datum;"
+            if type.n_min == 1 and type.n_max == 1:
+                print "    union ovsdb_atom key;"
+                if type.value:
+                    print "    union ovsdb_atom value;"
+                print
+                print "    ovs_assert(inited);"
+                print "    datum.n = 1;"
+                print "    datum.keys = &key;"
+                print "    " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
+                if type.value:
+                    print "    datum.values = &value;"
+                    print "    "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar)
+                else:
+                    print "    datum.values = NULL;"
+            elif type.is_optional_pointer():
+                print "    union ovsdb_atom key;"
+                print
+                print "    ovs_assert(inited);"
+                print "    if (%s) {" % keyVar
+                print "        datum.n = 1;"
+                print "        datum.keys = &key;"
+                print "        " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
+                print "    } else {"
+                print "        datum.n = 0;"
+                print "        datum.keys = NULL;"
+                print "    }"
+                print "    datum.values = NULL;"
+            elif type.n_max == 1:
+                print "    union ovsdb_atom key;"
+                print
+                print "    ovs_assert(inited);"
+                print "    if (%s) {" % nVar
+                print "        datum.n = 1;"
+                print "        datum.keys = &key;"
+                print "        " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar)
+                print "    } else {"
+                print "        datum.n = 0;"
+                print "        datum.keys = NULL;"
+                print "    }"
+                print "    datum.values = NULL;"
+            else:
+                print "    size_t i;"
+                print
+                print "    ovs_assert(inited);"
+                print "    datum.n = %s;" % nVar
+                print "    datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar)
+                if type.value:
+                    print "    datum.values = xmalloc(%s * sizeof *datum.values);" % nVar
+                else:
+                    print "    datum.values = NULL;"
+                print "    for (i = 0; i < %s; i++) {" % nVar
+                print "        " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar)
+                if type.value:
+                    print "        " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar)
+                print "    }"
+                if type.value:
+                    valueType = type.value.toAtomicType()
+                else:
+                    valueType = "OVSDB_TYPE_VOID"
+                print "    ovsdb_datum_sort_unique(&datum, %s, %s);" % (
+                    type.key.toAtomicType(), valueType)
+
+            print"""    ovsdb_idl_condition_add_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s],
+                          function,
+                          &%(s)s_columns[%(S)s_COL_%(C)s],
+                          &datum);
+}""" % {'t': tableName,
+       'T': tableName.upper(),
+       'p': prefix,
+       'P': prefix.upper(),
+       's': structName,
+       'S': structName.upper(),
+       'c': columnName,
+       'C': columnName.upper()}
+
+        print """void
+%(s)s_add_clause_false(struct ovsdb_idl *idl)
+{
+    struct ovsdb_datum datum;
+
+    ovsdb_datum_init_empty(&datum);
+    ovsdb_idl_condition_add_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s], OVSDB_F_FALSE, NULL, &datum);
+}""" % {'s': structName,
+        'T': tableName.upper(),
+        'p': prefix,
+        'P': prefix.upper()}
+
+        print """void
+%(s)s_add_clause_true(struct ovsdb_idl *idl)
+{
+    struct ovsdb_datum datum;
+
+    ovsdb_datum_init_empty(&datum);
+    ovsdb_idl_condition_add_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s], OVSDB_F_TRUE, NULL, &datum);
+}""" % {'s': structName,
+        'T': tableName.upper(),
+        'p': prefix,
+        'P': prefix.upper()}
+
+        # Remove clause functions.
+        for columnName, column in sorted(table.columns.iteritems()):
+            type = column.type
+
+            comment, members = cMembers(prefix, tableName, columnName,
+                                        column, True)
+
+            if type.is_smap():
+                print comment
+                print """void
+%(s)s_remove_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function, const struct smap *%(c)s)
+{
+    struct ovsdb_datum datum;
+
+    ovs_assert(inited);
+    if (%(c)s) {
+        struct smap_node *node;
+        size_t i;
+
+        datum.n = smap_count(%(c)s);
+        datum.keys = xmalloc(datum.n * sizeof *datum.keys);
+        datum.values = xmalloc(datum.n * sizeof *datum.values);
+
+        i = 0;
+        SMAP_FOR_EACH (node, %(c)s) {
+            datum.keys[i].string = xstrdup(node->key);
+            datum.values[i].string = xstrdup(node->value);
+            i++;
+        }
+        ovsdb_datum_sort_unique(&datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
+    } else {
+        ovsdb_datum_init_empty(&datum);
+    }
+
+    ovsdb_idl_condition_remove_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s],
+                                      function,
+                                      &%(s)s_columns[%(S)s_COL_%(C)s],
+                                      &datum);
+}
+""" % {'t': tableName,
+       'T': tableName.upper(),
+       'p': prefix,
+       'P': prefix.upper(),
+       's': structName,
+       'S': structName.upper(),
+       'c': columnName,
+       'C': columnName.upper()}
+                continue
+
+            keyVar = members[0]['name']
+            nVar = None
+            valueVar = None
+            if type.value:
+                valueVar = members[1]['name']
+                if len(members) > 2:
+                    nVar = members[2]['name']
+            else:
+                if len(members) > 1:
+                    nVar = members[1]['name']
+
+            print comment
+            print 'void'
+            print '%(s)s_remove_clause_%(c)s(struct ovsdb_idl *idl, enum ovsdb_function function, %(args)s)' % \
+                {'s': structName, 'c': columnName,
+                 'args': ', '.join(['%(type)s%(name)s' % m for m in members])}
+            print "{"
+            print "    struct ovsdb_datum datum;"
+            if type.n_min == 1 and type.n_max == 1:
+                print "    union ovsdb_atom key;"
+                if type.value:
+                    print "    union ovsdb_atom value;"
+                print
+                print "    ovs_assert(inited);"
+                print "    datum.n = 1;"
+                print "    datum.keys = &key;"
+                print "    " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
+                if type.value:
+                    print "    datum.values = &value;"
+                    print "    "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar)
+                else:
+                    print "    datum.values = NULL;"
+            elif type.is_optional_pointer():
+                print "    union ovsdb_atom key;"
+                print
+                print "    ovs_assert(inited);"
+                print "    if (%s) {" % keyVar
+                print "        datum.n = 1;"
+                print "        datum.keys = &key;"
+                print "        " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
+                print "    } else {"
+                print "        datum.n = 0;"
+                print "        datum.keys = NULL;"
+                print "    }"
+                print "    datum.values = NULL;"
+            elif type.n_max == 1:
+                print "    union ovsdb_atom key;"
+                print
+                print "    ovs_assert(inited);"
+                print "    if (%s) {" % nVar
+                print "        datum.n = 1;"
+                print "        datum.keys = &key;"
+                print "        " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar)
+                print "    } else {"
+                print "        datum.n = 0;"
+                print "        datum.keys = NULL;"
+                print "    }"
+                print "    datum.values = NULL;"
+            else:
+                print "    size_t i;"
+                print
+                print "    ovs_assert(inited);"
+                print "    datum.n = %s;" % nVar
+                print "    datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar)
+                if type.value:
+                    print "    datum.values = xmalloc(%s * sizeof *datum.values);" % nVar
+                else:
+                    print "    datum.values = NULL;"
+                print "    for (i = 0; i < %s; i++) {" % nVar
+                print "        " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar)
+                if type.value:
+                    print "        " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar)
+                print "    }"
+                if type.value:
+                    valueType = type.value.toAtomicType()
+                else:
+                    valueType = "OVSDB_TYPE_VOID"
+                print "    ovsdb_datum_sort_unique(&datum, %s, %s);" % (
+                    type.key.toAtomicType(), valueType)
+
+            print"""    ovsdb_idl_condition_remove_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s],
+                          function,
+                          &%(s)s_columns[%(S)s_COL_%(C)s],
+                          &datum);
+}""" % {'t': tableName,
+       'T': tableName.upper(),
+       'p': prefix,
+       'P': prefix.upper(),
+       's': structName,
+       'S': structName.upper(),
+       'c': columnName,
+       'C': columnName.upper()}
+
+        print """void
+%(s)s_remove_clause_false(struct ovsdb_idl *idl)
+{
+    struct ovsdb_datum datum;
+
+    ovsdb_datum_init_empty(&datum);
+    ovsdb_idl_condition_remove_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s], OVSDB_F_FALSE, NULL, &datum);
+}""" % {'s': structName,
+       'T': tableName.upper(),
+       'p': prefix,
+       'P': prefix.upper()}
+
+        print """void
+%(s)s_remove_clause_true(struct ovsdb_idl *idl)
+{
+    struct ovsdb_datum datum;
+
+    ovsdb_datum_init_empty(&datum);
+    ovsdb_idl_condition_remove_clause(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s], OVSDB_F_TRUE, NULL, &datum);
+}""" % {'s': structName,
+        'T': tableName.upper(),
+        'p': prefix,
+        'P': prefix.upper(),}
+
         # Table columns.
         print "\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (
             structName, structName.upper())