Skip to content

Instantly share code, notes, and snippets.

@hugopeixoto
Created October 28, 2014 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugopeixoto/60fa1e19aa73ce4f8b62 to your computer and use it in GitHub Desktop.
Save hugopeixoto/60fa1e19aa73ce4f8b62 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <gettext-po.h>
#include <string.h>
#include <sqlite3.h>
#include <time.h>
#define ERROR_CHECK_KEEP(code, message) \
{ \
int v = (code); \
if (v != 0) { \
printf("error code: %d\n", v); \
puts(message); \
return v; \
} \
}
void error_fn (int severity,
po_message_t message,
const char *filename, size_t lineno, size_t column,
int multiline_p, const char *message_text) {}
void error2_fn (int severity,
po_message_t message1,
const char *filename1, size_t lineno1, size_t column1,
int multiline_p1, const char *message_text1,
po_message_t message2,
const char *filename2, size_t lineno2, size_t column2,
int multiline_p2, const char *message_text2) {}
typedef int (*po_callback) (const char* msgid, const char* msgstr, void*);
int po_iterate (const char* filename, po_callback callback, void* a_user_data)
{
po_xerror_handler derp;
po_file_t fp = NULL;
po_message_iterator_t it = NULL;
po_message_t message = NULL;
const char* const* domains = NULL;
const char* const* domain = NULL;
derp.xerror = &error_fn;
derp.xerror2 = &error2_fn;
if ((fp = po_file_read(filename, &derp)) == NULL) {
puts("error opening po");
return -1;
}
domains = po_file_domains(fp);
for (domain = domains; *domain; ++domain) {
it = po_message_iterator(fp, *domain);
while ((message = po_next_message(it)) != NULL) {
const char* msgid = NULL;
const char* msgstr = NULL;
callback(po_message_msgid(message), po_message_msgstr(message), a_user_data);
msgid = po_message_msgid_plural(message);
for (int i = 0; (msgstr = po_message_msgstr_plural(message, i)); ++i) {
callback(msgid, msgstr, a_user_data);
}
}
}
po_file_free(fp);
}
int callback (const char* msgid, const char* msgstr, void* a_user_data)
{
sqlite3_stmt* stmt = (sqlite3_stmt*)a_user_data;
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 2, msgid, -1, SQLITE_STATIC), "error binding msgid");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 3, msgstr, -1, SQLITE_STATIC), "error binding msgstr");
ERROR_CHECK_KEEP(sqlite3_step(stmt) - SQLITE_DONE, "error executing statement");
ERROR_CHECK_KEEP(sqlite3_reset(stmt), "error resetting statement");
}
int main (int argc, char* argv[])
{
const char* repository_path = argv[1];
const char* filepath = argv[2];
int repository_id = atoi(argv[3]);
sqlite3* db = NULL;
sqlite3_stmt* stmt = NULL;
time_t now_raw;
struct tm* now_timeinfo;
char now_str[1024];
sqlite3_int64 file_id;
time(&now_raw);
now_timeinfo = localtime(&now_raw);
strftime(now_str, 1024, "%Y-%m-%d %H:%M:%S.000000", now_timeinfo);
ERROR_CHECK_KEEP(sqlite3_open_v2("db/development.sqlite3", &db, SQLITE_OPEN_READWRITE, NULL), "error opening database");
ERROR_CHECK_KEEP(sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL), "error executing begin");
ERROR_CHECK_KEEP(sqlite3_prepare_v2(db, "INSERT INTO translation_files (repository_id, filepath, created_at, updated_at) VALUES (?, ?, ?, ?);", -1, &stmt, NULL), "error creating statement");
ERROR_CHECK_KEEP(sqlite3_bind_int(stmt, 1, repository_id), "error binding repository_id");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 2, filepath, -1, SQLITE_STATIC), "error binding filepath");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 3, now_str, -1, SQLITE_STATIC), "error binding updated_at");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 4, now_str, -1, SQLITE_STATIC), "error binding created_at");
ERROR_CHECK_KEEP(sqlite3_step(stmt) - SQLITE_DONE, "error executing statement");
ERROR_CHECK_KEEP(sqlite3_finalize(stmt), "error destroying statement");
file_id = sqlite3_last_insert_rowid(db);
ERROR_CHECK_KEEP(sqlite3_prepare_v2(db, "INSERT INTO translations (translation_file_id, msgid, msgstr, created_at, updated_at) VALUES (?, ?, ?, ?, ?);", -1, &stmt, NULL), "error creating statement");
ERROR_CHECK_KEEP(sqlite3_bind_int64(stmt, 1, file_id), "error binding file_id");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 4, now_str, -1, SQLITE_STATIC), "error binding updated_at");
ERROR_CHECK_KEEP(sqlite3_bind_text(stmt, 5, now_str, -1, SQLITE_STATIC), "error binding created_at");
char buffer[4096] = { 0 };
strcat(buffer, repository_path);
strcat(buffer, "/");
strcat(buffer, filepath);
printf("Opening %s\n", buffer);
po_iterate(buffer, &callback, stmt);
ERROR_CHECK_KEEP(sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL), "error executing commit.");
ERROR_CHECK_KEEP(sqlite3_finalize(stmt), "error destroying statement");
ERROR_CHECK_KEEP(sqlite3_close(db), "error closing database");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment