+static gboolean
+append_summary_field (GArray *array,
+ EContactField field,
+ gboolean *have_attr_list,
+ GError **error)
+{
+ const gchar *dbname = NULL;
+ GType type = G_TYPE_INVALID;
+ gint i;
+ SummaryField new_field = { 0, };
+
+ if (field < 1 || field >= E_CONTACT_FIELD_LAST) {
+ g_set_error (error, E_BOOK_SDB_ERROR,
+ 0, _("Invalid contact field '%d' specified in summary"), field);
+ return FALSE;
+ }
+
+ /* Avoid including the same field twice in the summary */
+ for (i = 0; i < array->len; i++) {
+ SummaryField *iter = &g_array_index (array, SummaryField, i);
+ if (field == iter->field)
+ return TRUE;
+ }
+
+ /* Resolve some exceptions, we store these
+ * specific contact fields with different names
+ * than those found in the EContactField table
+ */
+ switch (field) {
+ case E_CONTACT_UID:
+ dbname = "uid";
+ break;
+ case E_CONTACT_IS_LIST:
+ dbname = "is_list";
+ break;
+ default:
+ dbname = e_contact_field_name (field);
+ break;
+ }
+
+ type = e_contact_field_type (field);
+
+ if (type != G_TYPE_STRING &&
+ type != G_TYPE_BOOLEAN &&
+ type != E_TYPE_CONTACT_ATTR_LIST) {
+ g_set_error (error, E_BOOK_SDB_ERROR, 0,
+ _("Contact field '%s' of type '%s' specified in summary, "
+ "but only boolean, string and string list field types are supported"),
+ e_contact_pretty_name (field), g_type_name (type));
+ return FALSE;
+ }
+
+ if (type == E_TYPE_CONTACT_ATTR_LIST)
+ *have_attr_list = TRUE;
+
+ new_field.field = field;
+ new_field.dbname = dbname;
+ new_field.type = type;
+ g_array_append_val (array, new_field);
+
+ return TRUE;
+}
+
+static void
+summary_fields_add_indexes (GArray *array,
+ EContactField *indexes,
+ EBookIndexType *index_types,
+ gint n_indexes,
+ gboolean *have_attr_list_prefix,
+ gboolean *have_attr_list_suffix)
+{
+ gint i, j;
+
+ for (i = 0; i < array->len; i++) {
+ SummaryField *sfield = &g_array_index (array, SummaryField, i);
+
+ for (j = 0; j < n_indexes; j++) {
+ if (sfield->field == indexes[j]) {
+ switch (index_types[j]) {
+ case E_BOOK_INDEX_PREFIX:
+ sfield->index |= INDEX_PREFIX;
+
+ if (sfield->type == E_TYPE_CONTACT_ATTR_LIST)
+ *have_attr_list_prefix = TRUE;
+ break;
+ case E_BOOK_INDEX_SUFFIX:
+ sfield->index |= INDEX_SUFFIX;
+
+ if (sfield->type == E_TYPE_CONTACT_ATTR_LIST)
+ *have_attr_list_suffix = TRUE;
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * e_book_backend_sqlitedb_new_full:
+ * @path: location where the db would be created
+ * @emailid: email id of the user
+ * @folderid: folder id of the address-book
+ * @folder_name: name of the address-book
+ * @store_vcard: True if the vcard should be stored inside db, if FALSE only the summary fields would be stored inside db.
+ * @setup: an #ESourceBackendSummarySetup describing how the summary should be setup
+ * @error: A location to store any error that may have occurred
+ *
+ * Like e_book_backend_sqlitedb_new(), but allows configuration of which contact fields
+ * will be stored for quick reference in the summary. The configuration indicated by
+ * @setup will only be taken into account when initially creating the underlying table,
+ * further configurations will be ignored.
+ *
+ * The fields %E_CONTACT_UID and %E_CONTACT_REV are not optional,
+ * they will be stored in the summary regardless of this function's parameters
+ *
+ * <note><para>Only #EContactFields with the type #G_TYPE_STRING, #G_TYPE_BOOLEAN or
+ * #E_TYPE_CONTACT_ATTR_LIST are currently supported.</para></note>
+ *
+ * Returns: (transfer full): The newly created #EBookBackendSqliteDB
+ *
+ * Since: 3.8
+ **/
+EBookBackendSqliteDB *
+e_book_backend_sqlitedb_new_full (const gchar *path,
+ const gchar *emailid,
+ const gchar *folderid,
+ const gchar *folder_name,
+ gboolean store_vcard,
+ ESourceBackendSummarySetup *setup,
+ GError **error)
+{
+ EBookBackendSqliteDB *ebsdb = NULL;
+ EContactField *fields;
+ EContactField *indexed_fields;
+ EBookIndexType *index_types = NULL;
+ gboolean have_attr_list = FALSE;
+ gboolean have_attr_list_prefix = FALSE;
+ gboolean have_attr_list_suffix = FALSE;
+ gboolean had_error = FALSE;
+ GArray *summary_fields;
+ gint n_fields = 0, n_indexed_fields = 0, i;
+
+ fields = e_source_backend_summary_setup_get_summary_fields (setup, &n_fields);
+ indexed_fields = e_source_backend_summary_setup_get_indexed_fields (setup, &index_types, &n_indexed_fields);
+
+ /* No specified summary fields indicates the default summary configuration should be used */
+ if (n_fields <= 0) {
+ ebsdb = e_book_backend_sqlitedb_new (path, emailid, folderid, folder_name, store_vcard, error);
+ g_free (fields);
+ g_free (index_types);
+ g_free (indexed_fields);
+
+ return ebsdb;
+ }
+
+ summary_fields = g_array_new (FALSE, FALSE, sizeof (SummaryField));
+
+ /* Ensure the non-optional fields first */
+ append_summary_field (summary_fields, E_CONTACT_UID, &have_attr_list, error);
+ append_summary_field (summary_fields, E_CONTACT_REV, &have_attr_list, error);
+
+ for (i = 0; i < n_fields; i++) {
+ if (!append_summary_field (summary_fields, fields[i], &have_attr_list, error)) {
+ had_error = TRUE;
+ break;
+ }
+ }
+
+ if (had_error) {
+ g_array_free (summary_fields, TRUE);
+ g_free (fields);
+ g_free (index_types);
+ g_free (indexed_fields);
+ return NULL;
+ }
+
+ /* Add the 'indexed' flag to the SummaryField structs */
+ summary_fields_add_indexes (summary_fields, indexed_fields, index_types, n_indexed_fields,
+ &have_attr_list_prefix, &have_attr_list_suffix);
+
+ ebsdb = e_book_backend_sqlitedb_new_internal (path, emailid, folderid, folder_name,
+ store_vcard,
+ (SummaryField *) summary_fields->data,
+ summary_fields->len,
+ have_attr_list,
+ have_attr_list_prefix,
+ have_attr_list_suffix,
+ error);
+
+ g_free (fields);
+ g_free (index_types);
+ g_free (indexed_fields);
+ g_array_free (summary_fields, FALSE);
+
+ return ebsdb;
+}
+
+
+
+/**
+ * e_book_backend_sqlitedb_new
+ * @path: location where the db would be created
+ * @emailid: email id of the user
+ * @folderid: folder id of the address-book
+ * @folder_name: name of the address-book
+ * @store_vcard: True if the vcard should be stored inside db, if FALSE only the summary fields would be stored inside db.
+ * @error:
+ *
+ * If the path for multiple addressbooks are same, the contacts from all addressbooks
+ * would be stored in same db in different tables.
+ *
+ * Returns:
+ *
+ * Since: 3.2
+ **/
+EBookBackendSqliteDB *
+e_book_backend_sqlitedb_new (const gchar *path,
+ const gchar *emailid,
+ const gchar *folderid,
+ const gchar *folder_name,
+ gboolean store_vcard,
+ GError **error)
+{
+ EBookBackendSqliteDB *ebsdb;
+ GArray *summary_fields;
+ gboolean have_attr_list = FALSE;
+ gboolean have_attr_list_prefix = FALSE;
+ gboolean have_attr_list_suffix = FALSE;
+ gint i;
+
+ /* Create the default summary structs */
+ summary_fields = g_array_new (FALSE, FALSE, sizeof (SummaryField));
+ for (i = 0; i < G_N_ELEMENTS (default_summary_fields); i++)
+ append_summary_field (summary_fields, default_summary_fields[i], &have_attr_list, NULL);
+
+ /* Add the default index flags */
+ summary_fields_add_indexes (summary_fields,
+ default_indexed_fields,
+ default_index_types,
+ G_N_ELEMENTS (default_indexed_fields),
+ &have_attr_list_prefix, &have_attr_list_suffix);
+
+ ebsdb = e_book_backend_sqlitedb_new_internal (path, emailid, folderid, folder_name,
+ store_vcard,
+ (SummaryField *) summary_fields->data,
+ summary_fields->len,
+ have_attr_list,
+ have_attr_list_prefix,
+ have_attr_list_suffix,
+ error);
+ g_array_free (summary_fields, FALSE);
+
+ return ebsdb;
+}
+