I am creating two tables with the following queries. Based on the region, the number of columns might be different and some columns might not be used for some regions.
String currentTableQuery = "CREATE TABLE \"" + currentTable + "\" \n" +
"AS \n" +
"SELECT " + columns + "\n" +
"FROM \"" + region + "\" \n" +
"WHERE partition_0=\'" + date + "\' AND partition_1=\'" + table + "\';";
Columns is an array:
String[] columns = new String[]{"col0", "col1", "col2", "col3", "col4", ...
Previous table:
String previousTableQuery = "CREATE TABLE \"" + previousTable + "\" \n" +
"AS \n" +
"SELECT " + columns + "\n" +
"FROM \"" + region + "\" \n" +
"WHERE partition_0=\'" + previousDate + "\' AND partition_1=\'" + table + "\';";
And after this, I am creating a delta table like below:
String deltaProcessingQuery =
"CREATE TABLE " + deltaTable + "\n" +
"WITH (\n" +
"format = 'TEXTFILE', \n" +
"field_delimiter = '\\t', \n" +
"write_compression = 'NONE', \n" +
"external_location = \'" + uploadLocation + "\' \n" +
")" + "\n" +
"AS" + "\n" +
"SELECT * FROM \"" + currentTable + "\" \n" +
"EXCEPT" + "\n" +
"SELECT * FROM \"" + previousTable + "\" ;";
But in the final delta table, columns which do not have data (or are extra columns) are backfilled with garbage data: \N. I am not sure where this data (\N) is coming from. How can I change that to be empty data?
Related
I'm trying to parse date time from a PNG file but can't quite get it with QRegExp
this_png_20211208_1916.png
QDateTime Product::GetObstime()
{
QDateTime obstime;
QString filename = FLAGS_file_name.c_str();
QString year, month, day, hour, minute, second;
QRegExp regexp = QRegExp("^.*\\w+_(\\d{4}\\d{2}\\d{2})_(\\d{2}\\d{2})\\.png$");
VLOG(3) << " filename: " << filename.toStdString();
if(regexp.indexIn(filename) !=-1)
{
VLOG(3) << " filename: " << filename.toStdString();
QStringList dt_bits = regexp.capturedTexts();
if(dt_bits.size() >=2)
{
year = dt_bits.at(1).mid(0, 4);
month = dt_bits.at(1).mid(5, 2);
day = dt_bits.at(1).mid(8, 2);
hour = dt_bits.at(2).mid(0, 2);
minute = dt_bits.at(2).mid(3, 2);
second = dt_bits.at(2).mid(3, 2);
VLOG(3) << " Year: " << year.toStdString()
<< " Month: " << month.toStdString()
<< " Day: " << day.toStdString()
<< " Hour: " << hour.toStdString()
<< " Min: " << minute.toStdString()
<< " Sec: " << second.toStdString();
QString datetime_str = year + "-" + month + "-" + day +
"T" + hour + ":" + minute + second + "00Z";
obstime = QDateTime::fromString(datetime_str, Qt::ISODate);
if (obstime.isValid())
{
VLOG(3)<<"Date iS VALID: "<<obstime.toString(Qt::ISODate).toStdString();
}
else
{
LOG(ERROR)<<" Error! Date Time bits did not match format.";
}
}
}
return obstime;
}
been using tools like https://regex101.com/
but to no avail. am I missing something?
You have the following errors in your code:
month = dt_bits.at(1).mid(5, 2); should be month = dt_bits.at(1).mid(4, 2); because the index is 0-based, not 1-based
day = dt_bits.at(1).mid(8, 2); should be day = dt_bits.at(1).mid(6, 2);
minute = dt_bits.at(2).mid(3, 2); should be minute = dt_bits.at(2).mid(2, 2);
second = dt_bits.at(2).mid(3, 2); should be second = "00"; because your filenames do not contain seconds
Generally I would recommend doing all of the work in the regex instead of doing some fancy splitting using QString::mid():
QRegExp regexp = QRegExp("^.*\\w+_(\\d{4})(\\d{2})(\\d{2})_(\\d{2})(\\d{2})\\.png$");
This gives you all the fields in separate groupings, no need for QString::mid() at all.
This question already has answers here:
How to concatenate a std::string and an int
(25 answers)
Closed 1 year ago.
#include <iostream>
#include <vector>
#include <string>
std::string likes(const std::vector<std::string> &names)
{
if (names.size() == 0)
return "no one likes this";
else if (names.size() == 1)
return names[0] + " likes this";
else if (names.size() == 2)
return names[0] + " and " + names[1] + " like this";
else if (names.size() == 3)
return names[0] + ", " + names[1] + " and " + names[2] + " like this";
else if(names.size() > 3)
return names[0] + ", " + names[1] + " and " + (names.size()-2) + " others like this"; /*this line isn't working, i guess the problem is in names.size() */
The last line is causing my application to not run, i have tried every possible way i know to solve this but nothing really helped, can you please help?
you can't concatenate a str with an int/float
corrected code:
#include <iostream>
#include <vector>
#include <string>
std::string likes(const std::vector<std::string> &names)
{
if (names.size() == 0)
return "no one likes this";
else if (names.size() == 1)
return names[0] + " likes this";
else if (names.size() == 2)
return names[0] + " and " + names[1] + " like this";
else if (names.size() == 3)
return names[0] + ", " + names[1] + " and " + names[2] + " like this";
else if(names.size() > 3)
return names[0] + ", " + names[1] + " and " + std::to_string(names.size()-2) + " others like this";
I have a program that basically opens a .sql database file and returns the table names into a string vector. This string vector is stored as tableNames and contains the tables within a given database file. For some reason that I cannot understand, the tableName parameter in the sqlCreateTemp string is not updated, but the varible tableName is.
void fileWrite()
{
string tableName;
string sqlCreateTemp = "CREATE TABLE tempLog AS SELECT * FROM " + tableName + "; UPDATE tempLog SET TIMESTAMP1=strftime('%s', datetime(timestamp1, 'localtime')) + strftime('%f', timestamp1) - strftime('%S', timestamp1);";
int rc = -1;
vector<string> tableNames = getTableNames();
for(int i = 0; i < tableNames.size(); i++)
{
cout << "TABLENAMES = " << tableNames[i] << endl;
tableName = tableNames[i] ;
cout << "tableName = " tableName << endl;
cout << "SQL = " << sqlCreateTemp << endl;
}
}
output:
TABLENAMES = testTableABC
tableName = testTableABC
SQL = CREATE TABLE tempLog AS SELECT * FROM ; UPDATE tempLog SET TIMESTAMP1=strftime('%s', datetime(timestamp1, 'localtime')) + strftime('%f', timestamp1) - strftime('%S', timestamp1);
Your computer executes your code one statement at a time, in a logical manner.
string tableName;
This creates a new std::string. It is an empty string.
string sqlCreateTemp = "CREATE TABLE tempLog AS SELECT * FROM " + tableName + ...
This creates another std::string, whose contents includes tableName. Which is empty, as we've just observed, so this part of sqlCreateTemp's contents is empty.
Code that executes later then sets new values of tableName:
tableName = tableNames[i] ;
That's fine, but this does not automatically change the contents of sqlCreateName. C++ does not work this way. Its value was set at the beginning of this function, and is never changed again. At the time that it was set, tableName was an empty string, and that's that.
If you want to create a new value of sqlCreateTemp each time tableName changes, you have to write the code to do it. The Golden Rule Of Computer Programming says, after all: your computer always does exactly, and precisely, what you tell it to do, instead of what you want it to do. If you want your computer to change the value of sqlCreateTemp, each time tableName's value changes, you must tell your computer to do that, exactly.
You need update the sqlCreateTemp after you update tableName variable, like this:
...
for(int i = 0; i < tableNames.size(); i++)
{
cout << "TABLENAMES = " << tableNames[i] << endl;
tableName = tableNames[i] ;
sqlCreateTemp = "CREATE TABLE tempLog AS SELECT * FROM " + tableName + "; UPDATE tempLog SET TIMESTAMP1=strftime('%s', datetime(timestamp1, 'localtime')) + strftime('%f', timestamp1) - strftime('%S', timestamp1);";
cout << "tableName = " tableName << endl;
cout << "SQL = " << sqlCreateTemp << endl;
}
...
Do it this way so that your tableName variable gets updated:
void fileWrite()
{
string tableName;
string sqlCreateTemp_part1 = "CREATE TABLE tempLog AS SELECT * FROM ";
string sqlCreateTemp_part2 = "; UPDATE tempLog SET TIMESTAMP1=strftime('%s', datetime(timestamp1, 'localtime')) + strftime('%f', timestamp1) - strftime('%S', timestamp1);";
string sqlCreateTemp;
int rc = -1;
vector<string> tableNames = getTableNames();
for(int i = 0; i < tableNames.size(); i++)
{
cout << "TABLENAMES = " << tableNames[i] << endl;
tableName = tableNames[i] ;
cout << "tableName = " tableName << endl;
sqlCreateTemp = sqlCreateTemp_part1 + tableName + sqlCreateTemp_part2;
cout << "SQL = " << sqlCreateTemp + << endl;
}
}
I am trying to insert into my SQL database using QT. I have been successful with other SQL commands like delete. But here Nothing is added to my database. I am wondering if maybe there is a syntax error somewhere.
QSqlQuery task;
task.prepare("insert or replace into animals(name, type, breed, gender, age, lifespan, noise, intelligence, adaptability, personality, diet, environment, pastOwners, timeDedication, costDedication, medication, reproductability, appetite, energyLevel, weight, height) values ('" + name + "', '" + type + "','" + breed + "','" + gender + "', " + age + ", " + lifespan + ", " + noise + ", " + intelligence + ", " + adaptability + " ,'" + personality + "', '" + diet + "', '" + environment + "', " + pastOwners + ", " + timeDedication + ", " + costDedication + ", " + medication + ", " + reproductability + ", '" + appetite + "', " + energyLevel + ", " + weight + ", " + height + ");");
task.exec();
For prepared query you need write something like this:
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();
Binding values will help avoid sql injection.
im wondering how to dynamicaly declare variable name with ionic 2.
i want to implemet a read more function with ion-list result but to do it i need to have individual variable names.
// my ts file
import { Component } from '#angular/core';
import { NavController,Platform ,LoadingController, NavParams } from 'ionic-
angular';
import { GardeService } from '../../app/services/Garde.service';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class Home {
//data:any;
public newslist: Array<Object>;
mytext:any;
prewords:any;
textpreview:any;
fulltext:any;
constructor(public data:GardeService) {}
ngOnInit()
{
this.loadnews();
this.fulltext = true;
this.textpreview = false;
}
public loadnews(){
this.newslist = [];
var map: {[key:string]:string} = {};
this.data.LoadNews().subscribe(
data => {
for(let i=0;i<data.length;i++){
//this.newslist.push(data[i]);
//console.log("news",data[i].content);
this.mytext = data[i].content.split(' ');
this.prewords = this.mytext[0] + " " + this.mytext[1] + " " +
this.mytext[2] + " " + this.mytext[3] + " " +
this.mytext[4] + " " + this.mytext[5] + " " + this.mytext[6] + " " +
this.mytext[7] + " " + this.mytext[8] + " " +
this.mytext[9] + " " + this.mytext[10] + " " + this.mytext[11] + " "
+ this.mytext[12] + " " + this.mytext[13] + " " +
this.mytext[14] + " " + this.mytext[15] + " " + this.mytext[16] + ""
+ this.mytext[17] + " " + this.mytext[18] + " " +
this.mytext[19] + " " + this.mytext[20];
//map['fulltext'+i] = true;
this.textpreview = false;
this.newslist.push({poster: data[i].poster, title: data[i].title,
img:data[i].img, content:data[i].content,
pre:this.prewords});
//console.log("les mots descriptifs",this.prewords);
}
},
err => {
console.log(err);
},
() => console.log('news loaded')
);
}
public readMore(){
this.textpreview = true;
this.fulltext = false;
}
}
// my html file
ion-col width-100 text-wrap>
<p style="text-align:justify;" color="dark" ion-text>
<span ion-text [hidden]="textpreview">{{item.pre}}</span><span
ion-text (click)="readMore()">...Lire plus</span>
<span ion-text [hidden]="fulltext">{{item.content}}</span>
</p>
</ion-col>
i want to have dynamic changing this.fulltext and this.textpreview variable names in order to do that because when i click the read more link all the content of all the ion-itens extend . i only want it to happen the place i click