<commit_before>const Datastore = require('nedb');
const {app} = require('electron').remote;

module.exports = function () {
	const self = this;
	this.db;
	let fileDB = app.getAppPath() + '/resources/db/data.store';

	this.init = function (readyCallback) {
		self.db = new Datastore({filename: fileDB, timestampData: true});
		self.db.loadDatabase(function () {
			self.db.find({type: 'playlist'}, function (err, docs) {
				if (docs.length === 0) {
					self.db.insert({type: 'playlist', name: 'Default'});
				}
				let folder = app.getPath('music');
				self.db.find({type: 'config', identifier: 'folder'}, function (err, docs) {
					if (docs.length === 0) {
						self.db.insert({type: 'playlist', identifier: 'folder', folder});
					}
					if (readyCallback) {
						readyCallback();
					}
				});
			});

		});
	};
	/*
	[{
	 type: 'config'
	 identifier:
	 value:
	}]
	*/

	this.getConfig = function (responseCallback) {
		self.db.find({type: 'config'}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.changeConfig = function (identifier, value, successCallback) {
		self.db.findOne({type: 'config', identifier: identifier}, function (err, doc) {
			if (doc !== null) {
				self.db.update({_id: doc._id}, {$set: {value: value}}, {}, function () {
					successCallback();
				});
			} else {
				self.db.insert({type: 'config', identifier: identifier, value: value}, function () {
					successCallback();
				});
			}
		});
	};

	/*
	[{
	 type: 'playlist'
	 name:
	}]
	*/

	this.getPlayLists = function (responseCallback) {
		self.db.find({type: 'playlist'}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.addPlayList = function (name, successCallback) {
		self.db.insert({type: 'playlist', name: name}, function () {
			successCallback();
		});
	};

	this.changeNamePlayList = function (_id, name, successCallback) {
		self.db.update({_id: _id}, {$set: {name: name}}, {}, function () {
			successCallback();
		});
	};

	this.deletePlayList = function (_id, successCallback) {
		//delete songs on playlist
		self.db.remove({playlist: _id}, {multi: true}, function (err, numRemoved) {
			// delete playlist
			self.db.remove({_id: _id}, {}, function (err, numRemoved) {
				successCallback();
			});
		});
	};

	/*
	[{
	 type: 'song'
	 path:
	 name:
	 playlist:
	}]
	*/
	this.addSongs = function (songs) {
		this.db.insert(songs);
	};

	this.getSongs = function (playlist, responseCallback) {
		self.db.find({type: 'song', playlist: playlist}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.getSong = function (_id, responseCallback) {
		self.db.findOne({_id: _id}, function (err, docs) {
			responseCallback(docs);
		});
	};

	this.changeNameSong = function (_id, name, successCallback) {
		self.db.update({_id: _id}, {$set: {name: name}}, {}, function () {
			successCallback();
		});
	};

	this.deleteSong = function (_id, successCallback) {
		self.db.remove({_id: _id}, {}, function (err, numRemoved) {
			successCallback();
		});
	};

	this.__getSongs = function (_id, type, successCallback) {
		self.getSong(_id, function (song) {
			if (song !== null) {
				self.getSongs(song.playlist, function (songs) {
					let index = songs.findIndex(k => k._id === _id);
					let target;
					if (type === 'next') {
						target = this.__modulo(index + 1, songs.length);
					}
					if (type === 'prev') {
						target = this.__modulo(index - 1, songs.length);
					}
					if (type === 'rand') {
						target = Math.floor(Math.random() * songs.length);
					}
					if (typeof songs[target] !== 'undefined') {
						successCallback(songs[target]);
					}
				});
			}
		});
	};

	this.__modulo = function(_id, bounds) {
		return (_id % bounds + bounds) % bounds;
	}

	this.getNextSong = function (_id, successCallback) {
		this.__getSongs(_id, 'next', successCallback);
	};

	this.getPrevSong = function (_id, successCallback) {
		this.__getSongs(_id, 'prev', successCallback);
	};

	this.getRandomSong = function (_id, successCallback) {
		this.__getSongs(_id, 'rand', successCallback);
	};

	this.updateDuratioSong = function (_id, duration, successCallback) {
		self.db.update({_id: _id}, {$set: {duration: duration}}, {}, function () {
			successCallback();
		});
	};

	this.setConfig = function (key, value) {
		// this.writeDB('UPDATE config set ' + key + ' = \'' + value + '\'');
	};

	this.getConfig = function (callback) {
		this.db.find({type: 'config'}, function (err, docs) {
			callback(docs);
		});
	};<commit_msg>Declare modulo function at the beggining like its done with sectostr<commit_after>const Datastore = require('nedb');
const {app} = require('electron').remote;

function modulo(_id, bounds) {
	return (_id % bounds + bounds) % bounds;
}

module.exports = function () {
	const self = this;
	this.db;
	let fileDB = app.getAppPath() + '/resources/db/data.store';

	this.init = function (readyCallback) {
		self.db = new Datastore({filename: fileDB, timestampData: true});
		self.db.loadDatabase(function () {
			self.db.find({type: 'playlist'}, function (err, docs) {
				if (docs.length === 0) {
					self.db.insert({type: 'playlist', name: 'Default'});
				}
				let folder = app.getPath('music');
				self.db.find({type: 'config', identifier: 'folder'}, function (err, docs) {
					if (docs.length === 0) {
						self.db.insert({type: 'playlist', identifier: 'folder', folder});
					}
					if (readyCallback) {
						readyCallback();
					}
				});
			});

		});
	};
	/*
	[{
	 type: 'config'
	 identifier:
	 value:
	}]
	*/

	this.getConfig = function (responseCallback) {
		self.db.find({type: 'config'}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.changeConfig = function (identifier, value, successCallback) {
		self.db.findOne({type: 'config', identifier: identifier}, function (err, doc) {
			if (doc !== null) {
				self.db.update({_id: doc._id}, {$set: {value: value}}, {}, function () {
					successCallback();
				});
			} else {
				self.db.insert({type: 'config', identifier: identifier, value: value}, function () {
					successCallback();
				});
			}
		});
	};

	/*
	[{
	 type: 'playlist'
	 name:
	}]
	*/

	this.getPlayLists = function (responseCallback) {
		self.db.find({type: 'playlist'}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.addPlayList = function (name, successCallback) {
		self.db.insert({type: 'playlist', name: name}, function () {
			successCallback();
		});
	};

	this.changeNamePlayList = function (_id, name, successCallback) {
		self.db.update({_id: _id}, {$set: {name: name}}, {}, function () {
			successCallback();
		});
	};

	this.deletePlayList = function (_id, successCallback) {
		//delete songs on playlist
		self.db.remove({playlist: _id}, {multi: true}, function (err, numRemoved) {
			// delete playlist
			self.db.remove({_id: _id}, {}, function (err, numRemoved) {
				successCallback();
			});
		});
	};

	/*
	[{
	 type: 'song'
	 path:
	 name:
	 playlist:
	}]
	*/
	this.addSongs = function (songs) {
		this.db.insert(songs);
	};

	this.getSongs = function (playlist, responseCallback) {
		self.db.find({type: 'song', playlist: playlist}).sort({createdAt: 1}).exec(function (err, docs) {
			responseCallback(docs);
		});
	};

	this.getSong = function (_id, responseCallback) {
		self.db.findOne({_id: _id}, function (err, docs) {
			responseCallback(docs);
		});
	};

	this.changeNameSong = function (_id, name, successCallback) {
		self.db.update({_id: _id}, {$set: {name: name}}, {}, function () {
			successCallback();
		});
	};

	this.deleteSong = function (_id, successCallback) {
		self.db.remove({_id: _id}, {}, function (err, numRemoved) {
			successCallback();
		});
	};

	this.__getSongs = function (_id, type, successCallback) {
		self.getSong(_id, function (song) {
			if (song !== null) {
				self.getSongs(song.playlist, function (songs) {
					let index = songs.findIndex(k => k._id === _id);
					let target;
					if (type === 'next') {
						target = modulo(index + 1, songs.length);
					}
					if (type === 'prev') {
						target = modulo(index - 1, songs.length);
					}
					if (type === 'rand') {
						target = Math.floor(Math.random() * songs.length);
					}
					if (typeof songs[target] !== 'undefined') {
						successCallback(songs[target]);
					}
				});
			}
		});
	};

	this.getNextSong = function (_id, successCallback) {
		this.__getSongs(_id, 'next', successCallback);
	};

	this.getPrevSong = function (_id, successCallback) {
		this.__getSongs(_id, 'prev', successCallback);
	};

	this.getRandomSong = function (_id, successCallback) {
		this.__getSongs(_id, 'rand', successCallback);
	};

	this.updateDuratioSong = function (_id, duration, successCallback) {
		self.db.update({_id: _id}, {$set: {duration: duration}}, {}, function () {
			successCallback();
		});
	};

	this.setConfig = function (key, value) {
		// this.writeDB('UPDATE config set ' + key + ' = \'' + value + '\'');
	};

	this.getConfig = function (callback) {
		this.db.find({type: 'config'}, function (err, docs) {
			callback(docs);
		});
	};
{'fraction_non_alphanumeric': 0.1901954361829894, 'fraction_numerical': 0.001528551151872475, 'mean_word_length': 3.516765285996055, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3720746', 'n_tokens_mistral': 3620, 'n_tokens_neox': 3053, 'n_words': 646}