В общем, эмпирическое правило заключается в том, чтобы все модели, которые связаны с обработкой данных и выполнением запросов к базе данных, входили в модель. У разных разработчиков разные методы, но я думаю, что вы не должны ломать модель MVC и помещать код базы данных в свои контроллеры.
Я сам разрабатывал библиотеку аутентификации под названием WolfAuth, чтобы кто-нибудь тоже мог ее использовать и внести свой вклад: https://github.com/Vheissu/WolfAuth-for-Codeigniter-2.0-
Как вы можете видеть в моей модели, у меня есть функция get, которая может принимать значения иголки и стога сена. Таким образом, я могу написать целую кучу различных функций в моей библиотеке для получения пользователя по идентификатору или входа пользователя в систему, вызывая функцию этой модели с разными параметрами вместо вызова разных функций.
В WolfAuth вы можете видеть, что все функции будут вызывать функцию модели get_users с разными значениями. Я считаю, что наличие одной функции, которая может извлекать несколько фрагментов данных вместо написания отдельных функций, намного чище, чем наличие 6 функций, когда одна функция может делать все, что могут делать эти 6 функций.
Итак, чтобы ответить на ваш вопрос: напишите функцию, которая взаимодействует с базой данных в вашей модели, но оставьте ту же функцию в вашей библиотеке для вызова функции модели и возврата ее значения.
Кроме того, если вы хотите свободно брать фрагменты кода и заимствовать идеи из моей библиотеки аутентификации и использовать их в своей, если это поможет вам лучше разбить код на части.