From be9de8b2e0864b46498496af9ffdc31c0e7b764a Mon Sep 17 00:00:00 2001
From: Daniel Kamil Kozar <dkk089@gmail.com>
Date: Sun, 16 Dec 2018 14:21:58 +0100
Subject: [PATCH] Reduce duplication in sql.c

---
 sql.c | 166 ++++++++++++++++++++--------------------------------------
 1 file changed, 58 insertions(+), 108 deletions(-)

--- a/sql.c
+++ b/sql.c
@@ -65,122 +65,72 @@ sql_get_table(sqlite3 *db, const char *s
 	return ret;
 }
 
+#define sql_get_field(type, column_get_fn) \
+		va_list		ap;\
+		int		counter, result;\
+		char		*sql;\
+		type		ret;\
+		sqlite3_stmt	*stmt;\
+		\
+		va_start(ap, fmt);\
+		sql = sqlite3_vmprintf(fmt, ap);\
+		va_end(ap);\
+\
+		/*DPRINTF(E_DEBUG, L_DB_SQL, "sql: %s\n", sql); */ \
+\
+		switch (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))\
+		{\
+			case SQLITE_OK:\
+				break;\
+			default:\
+				DPRINTF(E_ERROR, L_DB_SQL, "prepare failed: %s\n%s\n", sqlite3_errmsg(db), sql);\
+				sqlite3_free(sql);\
+				return -1;\
+		}\
+\
+		for (counter = 0;\
+		     ((result = sqlite3_step(stmt)) == SQLITE_BUSY || result == SQLITE_LOCKED) && counter < 2;\
+		     counter++) {\
+			/* While SQLITE_BUSY has a built in timeout,\
+			 * SQLITE_LOCKED does not, so sleep */\
+			if (result == SQLITE_LOCKED)\
+				sleep(1);\
+		}\
+\
+		switch (result)\
+		{\
+			case SQLITE_DONE:\
+				/* no rows returned */\
+				ret = 0;\
+				break;\
+			case SQLITE_ROW:\
+				if (sqlite3_column_type(stmt, 0) == SQLITE_NULL)\
+				{\
+					ret = 0;\
+					break;\
+				}\
+				ret = column_get_fn(stmt, 0);\
+				break;\
+			default:\
+				DPRINTF(E_WARN, L_DB_SQL, "%s: step failed: %s\n%s\n", __func__, sqlite3_errmsg(db), sql);\
+				ret = -1;\
+				break;\
+		}\
+		sqlite3_free(sql);\
+		sqlite3_finalize(stmt);\
+\
+		return ret;
+
 int
 sql_get_int_field(sqlite3 *db, const char *fmt, ...)
 {
-	va_list		ap;
-	int		counter, result;
-	char		*sql;
-	int		ret;
-	sqlite3_stmt	*stmt;
-	
-	va_start(ap, fmt);
-	sql = sqlite3_vmprintf(fmt, ap);
-	va_end(ap);
-
-	//DPRINTF(E_DEBUG, L_DB_SQL, "sql: %s\n", sql);
-
-	switch (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))
-	{
-		case SQLITE_OK:
-			break;
-		default:
-			DPRINTF(E_ERROR, L_DB_SQL, "prepare failed: %s\n%s\n", sqlite3_errmsg(db), sql);
-			sqlite3_free(sql);
-			return -1;
-	}
-
-	for (counter = 0;
-	     ((result = sqlite3_step(stmt)) == SQLITE_BUSY || result == SQLITE_LOCKED) && counter < 2;
-	     counter++) {
-		/* While SQLITE_BUSY has a built in timeout,
-		 * SQLITE_LOCKED does not, so sleep */
-		if (result == SQLITE_LOCKED)
-			sleep(1);
-	}
-
-	switch (result)
-	{
-		case SQLITE_DONE:
-			/* no rows returned */
-			ret = 0;
-			break;
-		case SQLITE_ROW:
-			if (sqlite3_column_type(stmt, 0) == SQLITE_NULL)
-			{
-				ret = 0;
-				break;
-			}
-			ret = sqlite3_column_int(stmt, 0);
-			break;
-		default:
-			DPRINTF(E_WARN, L_DB_SQL, "%s: step failed: %s\n%s\n", __func__, sqlite3_errmsg(db), sql);
-			ret = -1;
-			break;
-	}
-	sqlite3_free(sql);
-	sqlite3_finalize(stmt);
-
-	return ret;
+	sql_get_field(int, sqlite3_column_int)
 }
 
 int64_t
 sql_get_int64_field(sqlite3 *db, const char *fmt, ...)
 {
-	va_list		ap;
-	int		counter, result;
-	char		*sql;
-	int64_t		ret;
-	sqlite3_stmt	*stmt;
-	
-	va_start(ap, fmt);
-	sql = sqlite3_vmprintf(fmt, ap);
-	va_end(ap);
-
-	//DPRINTF(E_DEBUG, L_DB_SQL, "sql: %s\n", sql);
-
-	switch (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))
-	{
-		case SQLITE_OK:
-			break;
-		default:
-			DPRINTF(E_ERROR, L_DB_SQL, "prepare failed: %s\n%s\n", sqlite3_errmsg(db), sql);
-			sqlite3_free(sql);
-			return -1;
-	}
-
-	for (counter = 0;
-	     ((result = sqlite3_step(stmt)) == SQLITE_BUSY || result == SQLITE_LOCKED) && counter < 2;
-	     counter++) {
-		/* While SQLITE_BUSY has a built in timeout,
-		 * SQLITE_LOCKED does not, so sleep */
-		if (result == SQLITE_LOCKED)
-			sleep(1);
-	}
-
-	switch (result)
-	{
-		case SQLITE_DONE:
-			/* no rows returned */
-			ret = 0;
-			break;
-		case SQLITE_ROW:
-			if (sqlite3_column_type(stmt, 0) == SQLITE_NULL)
-			{
-				ret = 0;
-				break;
-			}
-			ret = sqlite3_column_int64(stmt, 0);
-			break;
-		default:
-			DPRINTF(E_WARN, L_DB_SQL, "%s: step failed: %s\n%s\n", __func__, sqlite3_errmsg(db), sql);
-			ret = -1;
-			break;
-	}
-	sqlite3_free(sql);
-	sqlite3_finalize(stmt);
-
-	return ret;
+	sql_get_field(int64_t, sqlite3_column_int64)
 }
 
 char *
