Skip to content

Instantly share code, notes, and snippets.

@ajdavis
Last active December 24, 2017 17:05
Show Gist options
  • Save ajdavis/07da0585f9d6613a979d12747d2b9a92 to your computer and use it in GitHub Desktop.
Save ajdavis/07da0585f9d6613a979d12747d2b9a92 to your computer and use it in GitHub Desktop.
IDL for C Driver - prototypes
* ``writeConcern``: Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`.
* ``sessionId``: Construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session` and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`.
* ``validate``: Construct a bitwise-or of all desired
`bson_validate_flags_t
<http://mongoc.org/libbson/current/bson_validate_with_error.html>`_. Set to ``0`` to skip client-side validation of the provided BSON documents.
* ``bypassDocumentValidation``: Set to ``true`` to skip server-side schema validation of the provided BSON documents.
* ``collation``: Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_.
* ``ordered``: set to ``false`` to attempt to insert all documents, continuing after errors.
# Example descriptions for three libmongoc functions:
# mongoc_collection_find_with_opts()
# mongoc_collection_insert_one()
# mongoc_collection_insert_many()
opts_structs = {
'mongoc_find_one_opts_t': {
'projection': {'type': 'doc'},
'sort': {'type': 'doc'},
'skip': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'limit': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'batchSize': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'exhaust': {'type': 'bool'},
'hint': {'type': ['utf8', 'document']},
'allowPartialResults': {'type': 'bool'},
'awaitData': {'type': 'bool'},
'collation': {'type': 'document'},
'comment': {'type': 'utf8'},
'max': {'type': 'document'},
'maxScan': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'maxTimeMS': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'maxAwaitTimeMS': {
'type': 'int64_t',
'convert': '_mongoc_convert_int64_positive'
},
'min': {'type': 'document'},
'noCursorTimeout': {'type': 'bool'},
'oplogReplay': {'type': 'bool'},
'returnKey': {'type': 'bool'},
'showRecordId': {'type': 'bool'},
'singleBatch': {'type': 'bool'},
'snapshot': {'type': 'bool'},
'tailable': {'type': 'bool'},
},
'mongoc_crud_opts_t': {
'writeConcern': {
'type': 'document',
'convert': '_mongoc_convert_write_concern',
'help': 'Construct a :symbol:`mongoc_write_concern_t` and use :symbol:`mongoc_write_concern_append` to add the write concern to ``opts``. See the example code for :symbol:`mongoc_client_write_command_with_opts`.'
},
'sessionId': {
'type': 'mongoc_client_session_t *',
'convert': '_mongoc_convert_session_id',
'field': 'client_session',
'help': 'Construct a :symbol:`mongoc_client_session_t` with :symbol:`mongoc_client_start_session` and use :symbol:`mongoc_client_session_append` to add the session to ``opts``. See the example code for :symbol:`mongoc_client_session_t`.'
},
'validate': {
'type': 'bson_validate_flags_t',
'convert': '_mongoc_convert_validate_flags',
'help': 'Construct a bitwise-or of all desired `bson_validate_flags_t <http://mongoc.org/libbson/current/bson_validate_with_error.html>`_. Set to ``0`` to skip client-side validation of the provided BSON documents.'
},
'bypassDocumentValidation': {
'type': 'bool',
'help': 'Set to ``true`` to skip server-side schema validation of the provided BSON documents.'
},
'collation': {
'type': 'document',
'help': 'Configure textual comparisons. See :ref:`Setting Collation Order <setting_collation_order>`, and `the MongoDB Manual entry on Collation <https://docs.mongodb.com/manual/reference/collation/>`_.'
},
},
'mongoc_insert_one_opts_t': {
'crud': {'type': 'mongoc_crud_opts_t'}
},
'mongoc_insert_many_opts_t': {
'crud': {'type': 'mongoc_crud_opts_t'},
'ordered': {'type': 'bool'}
},
}
def field_decl(name, info):
if info['type'] == 'utf8':
the_type = 'const char *'
elif info['type'] == 'document':
the_type = 'bson_t'
elif isinstance(info['type'], str):
the_type = info['type']
else:
# Type is a list of possibilities like ['utf8', 'document'].
the_type = 'bson_value_t'
the_name = info.get('field', name)
space = '' if the_type.endswith('*') else ' '
return '%s%s%s;' % (the_type, space, the_name)
for struct_name, desc in opts_structs.items():
print('typedef struct {')
for opt_name, opt_info in desc.items():
line = field_decl(opt_name, opt_info)
if line:
print(' ' + line)
print('} %s;' % struct_name)
print('')
#include <bson.h>
#include <mongoc.h>
/*
* write Python to generate these structs from the opts_structs dictionary
*/
typedef struct {
bson_t writeConcern;
mongoc_client_session_t *client_session;
bson_validate_flags_t validate;
bool bypassDocumentValidation;
bson_t collation;
} mongoc_crud_opts_t;
typedef struct {
mongoc_crud_opts_t crud;
} mongoc_insert_one_opts_t;
typedef struct {
mongoc_crud_opts_t crud;
bool ordered;
} mongoc_insert_many_opts_t;
/*
* we must declare and implement these functions, and more, by hand
*/
bool
_mongoc_convert_session_id (bson_iter_t *iter,
mongoc_client_session_t **value,
bson_error_t *error);
bool
_mongoc_convert_write_concern (bson_iter_t *iter,
bson_t *value,
bson_error_t *error);
bool
_mongoc_convert_validate_flags (bson_iter_t *iter,
bson_validate_flags_t *value,
bson_error_t *error);
bool
_mongoc_convert_bool (bson_iter_t *iter, bool *value, bson_error_t *error);
bool
_mongoc_convert_document (bson_iter_t *iter,
bson_t *value,
bson_error_t *error);
/*
* write Python to generate this function from opts_structs
*/
bool
parse_insert_many_opts (const bson_t *opts,
mongoc_insert_many_opts_t *insert_many_opts,
bson_t *extra,
bson_error_t *error)
{
bson_iter_t iter;
if (!bson_iter_init (&iter, opts)) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
while (bson_iter_next (&iter)) {
if (!strcmp (bson_iter_key (&iter), "writeConcern")) {
if (!_mongoc_convert_write_concern (
&iter, &insert_many_opts->crud.writeConcern, error)) {
return false;
}
} else if (!strcmp (bson_iter_key (&iter), "sessionId")) {
if (!_mongoc_convert_session_id (
&iter, &insert_many_opts->crud.client_session, error)) {
return false;
}
} else if (!strcmp (bson_iter_key (&iter), "validate")) {
if (!_mongoc_convert_validate_flags (
&iter, &insert_many_opts->crud.validate, error)) {
return false;
}
} else if (!strcmp (bson_iter_key (&iter), "bypassDocumentValidation")) {
if (!_mongoc_convert_bool (
&iter,
&insert_many_opts->crud.bypassDocumentValidation,
error)) {
return false;
}
} else if (!strcmp (bson_iter_key (&iter), "collation")) {
if (!_mongoc_convert_document (
&iter, &insert_many_opts->crud.collation, error)) {
return false;
}
} else if (!strcmp (bson_iter_key (&iter), "ordered")) {
if (!_mongoc_convert_bool (&iter, &insert_many_opts->ordered, error)) {
return false;
}
} else {
/* unrecognized values are copied to "extra" */
if (!bson_append_value (
extra, bson_iter_key (&iter), -1, bson_iter_value (&iter))) {
bson_set_error (error,
MONGOC_ERROR_BSON,
MONGOC_ERROR_BSON_INVALID,
"Invalid 'opts' parameter.");
return false;
}
}
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment