null userId, Unhandled Exception: Null check operator used on a null value - sql

I have an issue with userId in Habits table. it is a foreign key from id in Users Table. but I keep getting the error "Unhandled Exception: Null check operator used on a null value " from AddHabitDialogController class.
obviously userId should never be null. where is the issue? how can I solve it?
if more code is needed you can check : https://github.com/sarasoltan/habit_tracker
Users Table:
class UsersTable {
static const String tableName = 'Users';
static const String id = 'id';
static const String email = 'email';
static const String createQuery = '''
CREATE TABLE IF NOT EXISTS $tableName (
$id integer primary key autoincrement,
$email text not null unique);''';
#override
String toString() => 'Person, ID: $id, email: $email';
#override
bool operator ==(covariant Users other) => id == other.id;
#override
int get hashCode => id.hashCode;
}
Habits table:
class HabitsTable {
static const String tableName = 'Habits';
static const String id = 'id';
static const String userId = 'userId';
static const String text = 'text';
static const String emoji = 'emoji';
static const String period = 'period';
static const String startPeriod = 'startPeriod';
static const String createQuery = '''
CREATE TABLE IF NOT EXISTS $tableName (
$id integer primary key autoincrement,
$userId integer not null,
$text text not null,
$emoji text not null,
$period text not null,
$startPeriod integer,
FOREIGN Key($userId) REFERENCES ${UsersTable.tableName}(${UsersTable.id}));''';
User model class:
class Users {
late final int id;
late String email;
Users({
required this.id,
required this.email,
});
Users.fromDb(Map<String, dynamic> map) {
id = map[UsersTable.id];
email = map[UsersTable.email];
}
}
Habit model class:
class Habit {
late final int id;
late final int userId;
late String text;
late String emoji;
late final List<int> period;
late final DateTime? startPeriod;
Habit(
{
//required this.id,
required this.userId,
required this.text,
required this.emoji,
required this.period,
this.startPeriod});
Habit.fromDb(Map<String, dynamic> map) {
id = map[HabitsTable.id] as int;
userId = map[HabitsTable.userId] as int;
text = map[HabitsTable.text] as String;
emoji = map[HabitsTable.emoji];
period = (jsonDecode(map[HabitsTable.period]) as List<dynamic>)
.map((e) => e as int)
.toList();
if (map[HabitsTable.startPeriod] != null) {
startPeriod =
DateTime.fromMillisecondsSinceEpoch(map[HabitsTable.startPeriod]);
} else {
startPeriod = null;
}
}
Map<String, dynamic> toDb() {
Users? owner;
return {
//HabitsTable.id: id,
HabitsTable.userId: owner!.id,
HabitsTable.text: text,
HabitsTable.emoji: emoji,
HabitsTable.period: jsonEncode(period),
HabitsTable.startPeriod: startPeriod?.millisecondsSinceEpoch
};
}
AddHabitDialogController(error):
class AddHabitDialogController {
Users? owner;
//final user = FirebaseAuth.instance.currentUser;
//String get owneruserId => AuthService.firebase().currentUser!.id;
final List<bool> period = [true, true, true, true, true, true, true];
int? id;
int? userId;
String? emoji;
String? text;
StartPeriod startPeriod = StartPeriod.none;
final StreamController<bool> _addBtnEnabledCtrl = StreamController();
Stream<bool> get addBtnEnabled => _addBtnEnabledCtrl.stream;
final StreamController<StartPeriod> _selectedStartPeriodCtrl =
StreamController();
Stream<StartPeriod> get selectedStartPeriod =>
_selectedStartPeriodCtrl.stream;
final StreamController<bool> _loadingCtrl = StreamController();
Stream<bool> get loading => _loadingCtrl.stream;
void changePeriodValue(int index, bool newValue) {
period[index] = newValue;
_updateAddBtnEnabledState();
}
void changeTextValue(String newValue) {
text = newValue;
_updateAddBtnEnabledState();
}
void changeEmojiValue(String newEmoji) {
emoji = newEmoji;
_updateAddBtnEnabledState();
}
void changeStartPeriod(StartPeriod newValue) {
startPeriod = newValue;
_selectedStartPeriodCtrl.add(startPeriod);
}
Future<void> addHabit(BuildContext context) async {
_loadingCtrl.add(true);
final dataService = GetIt.I.get<DataService>();
final List<int> forPeriod = [];
for (int i = 0; i < period.length; i++) {
if (period[i]) {
forPeriod.add(i + 1);
}
}
final habit = Habit(
//id: id!,
userId: owner!.id, //error from here
emoji: emoji!,
text: text!,
period: forPeriod,
startPeriod: _calculateStartPeriodDateTime());
await dataService.addHabit(habit);
_loadingCtrl.add(false);
Navigator.of(context).pop();
}
void _updateAddBtnEnabledState() {
_addBtnEnabledCtrl.add((text?.isNotEmpty ?? false) &&
(emoji?.isNotEmpty ?? false) &&
period.where((e) => e).isNotEmpty);
}
DateTime? _calculateStartPeriodDateTime() {
final now = DateTime.now();
switch (startPeriod) {
case StartPeriod.today:
return DateTime(now.year, now.month, now.day);
case StartPeriod.thisMonth:
return DateTime(now.year, now.month);
case StartPeriod.thisYear:
return DateTime(now.year);
case StartPeriod.none:
default:
return null;
}
}
void dispose() {
_addBtnEnabledCtrl.close();
_loadingCtrl.close();
_selectedStartPeriodCtrl.close();
}
}
enum StartPeriod { none, today, thisMonth, thisYear }

Because the local variable of AddHabitDialogController owner can't be referenced before it is declared
class AddHabitDialogController {
Users? owner; // -> you did not assign this owner?

Related

DatabaseException(FOREIGN KEY constraint failed (code 787)) sql 'INSERT OR FAIL INTO

I'm having problem with foreign key while adding a new habit and inserting it's data in db and I don't really know why, because everything seems right. the error is:
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: DatabaseException(FOREIGN KEY constraint failed (code 787)) sql 'INSERT OR FAIL INTO Habits (userId, text, emoji, period, startPeriod) VALUES (?, ?, ?, ?, NULL)' args [1, habit, ☺, [1,2,3,4,5,6,7]]
error accrued here:
class DataService {...
late final Database db;
Future<void> addHabit(Habit newHabit) async {
final newHabitId = await HabitsDb.createHabit(db, newHabit);//error accrued here
final days = (await HabitsDb.getAllDays(db)).map((e) => Day.fromDb(e, []));
for (final day in days) {
if (newHabit.startPeriod != null &&
newHabit.startPeriod!.compareTo(day.date) > 0) {
continue;
}
if (newHabit.period.contains(day.date.weekday)) {
await HabitsDb.createHabitDay(
db, day.date.millisecondsSinceEpoch, newHabitId);
}
}
await _reloadDaysInCache();
_loadHabits();
} ...}
then:
class HabitsDb{...
static Future<int> createHabit(Database db, Habit habit) async {
return db.insert(HabitsTable.tableName, await habit.toDb(),
conflictAlgorithm: ConflictAlgorithm.fail);
}...}
model:
class Habit {
late final int id;
late final int userId;
late String text;
late String emoji;
late final List<int> period;
late final DateTime? startPeriod;
...
Future<Map<String, dynamic>> toDb() async {
print(text);
print(userId);
return {
//HabitsTable.id: id,
HabitsTable.userId: userId,
HabitsTable.text: text,
HabitsTable.emoji: emoji,
HabitsTable.period: jsonEncode(period),
HabitsTable.startPeriod: startPeriod?.millisecondsSinceEpoch
};
}...}
creating table:
class HabitsTable {
static const String tableName = 'Habits';
static const String id = 'id';
static const String userId = 'userId';
static const String text = 'text';
static const String emoji = 'emoji';
static const String period = 'period';
static const String startPeriod = 'startPeriod';
static const String createQuery = '''
CREATE TABLE IF NOT EXISTS $tableName (
$id INTEGER PRIMARY KEY AUTOINCREMENT,
$userId INTEGER NOT NULL,
$text TEXT NOT NULL,
$emoji TEXT NOT NULL,
$period TEXT NOT NULL,
$startPeriod INTEGER,
FOREIGN KEY($userId) REFERENCES ${UsersTable.tableName}(id));''';
}
if more code is needed you can check https://github.com/sarasoltan/habit_tracker
plz help if you know how to solve this error.

how to pass two or three values to fluent validation Must function?

my code :
public class MandatoryValidator : AbstractValidator<Entity.EigenSchema.AttributeSet>
{
private string Keyvalue = string.Empty;
public MandatoryValidator(string keyvalue)
{
Keyvalue = keyvalue;
RuleFor(record => record.Mandatory).Must(Mandatory);
}
protected bool Mandatory(bool val)
{
if (val)
{
if(Keyvalue!=null || Keyvalue!="")
{
return true;
}
return false;
}
else
{
return true;
}
}
}
this checks if the field is mandatory or not.
Now I need a function that takes more than one parameter to mandatory function, something like this..
protected bool Mandatory(bool val, string strval, int val)
{
//strval = record.LocalUnique
//val = record.Size
}
You can do it like this
RuleFor(record => record.Mandatory).Must(mandatoryField => Mandatory(mandatoryField, Keyvalue, 012));
You can also
RuleFor(record => record).Must(WholeObject=> Mandatory(WholeObject))
.WithName("Mandatory");
//.WithName(x => x.MandatoryFieldName) optional
//and now
private bool MandatorChecker(MyRecordType obj)
{
strval = obj.LocalUnique;
val = obj.Size;
}
This one will use the name you provided if this rule breaks.

It was okay until I tried to upgrade it to add one more column to it

I was learning to use sqlflite in my flutter application..when i upgraded it for the first time it worked absolutely fine..but then I wanted to add one more column but i actually don't know query for that.. so I tried the query shown below, but when I try to save my data, I get this error:
E/SQLiteLog(22556): (1) table tbl_employee has no column named employee_gender
I/flutter (22556): DatabaseException(table tbl_employee has no column named employee_gender (code 1 SQLITE_ERROR): , while compiling: INSERT OR REPLACE INTO tbl_employee (employee_name, employee_Student, employee_depertment, employee_DOB, employee_gender) VALUES (?, ?, ?, ?, ?)) sql 'INSERT OR REPLACE INTO tbl_employee (employee_name, employee_Student, employee_depertment, employee_DOB, employee_gender) VALUES (?, ?, ?, ?, ?)' args [Adrita, teacher, CMT, 19/00/2020, 2]}
This is my database class:
class DBHelper{
static final String CREATE_TABLE_EMPLOYEE = '''
create table $TABLE_EMPLOYEE(
$COL_EMP_ID integer primary key autoincrement,
$COL_EMP_NAME text not null,
$COL_EMP_PROFESSION text not null,
$COL_EMP_DEPARTMENT text not null
)
''';
static Future<Database> open() async{// to initialize data we used this method
final dbpath = await getDatabasesPath();//directory
final path = Path.join(dbpath,'employee.db');//main Path
return openDatabase(path,version: 3,onCreate: (db, version) async{
await db.execute(CREATE_TABLE_EMPLOYEE);
}, onUpgrade: (db, oldVersion, newVersion) async{
if(newVersion == 2){
db.execute(''' alter table $TABLE_EMPLOYEE add column $COL_EMP_DOB text ''');
}
if(newVersion == 3){
db.execute('''alter table $TABLE_EMPLOYEE add column $COL_RADIO_BUTTON integer ''');
}
},);
}
static Future<int> insertEmployee(String table, Map<String, dynamic> map) async {// insert method
final db = await open();
return await db.insert(table, map, conflictAlgorithm: ConflictAlgorithm.replace);
}
static Future<int> updateEmployee(EmployeeTeacherModel employeemodel) async{
final db = await open();
return await db.update(TABLE_EMPLOYEE, employeemodel.toMap(), where: '$COL_EMP_ID = ?', whereArgs: [employeemodel.id]);
}
static Future<int> DeleteEmployee(int id) async{
final db = await open();
return await db.delete(TABLE_EMPLOYEE,where: '$COL_EMP_ID = ?', whereArgs: [id]);
}
static Future<List<EmployeeTeacherModel>> getAllEmployees() async{
final db = await open();
final List<Map<String, dynamic>> map = await db.query(TABLE_EMPLOYEE, orderBy: COL_EMP_NAME);
return List.generate(map.length, (index){
return EmployeeTeacherModel.fromMap(map[index]);
});
}
static Future<EmployeeTeacherModel> getEmployeeByid(int id) async{
final db = await open();
final List<Map<String, dynamic>> emps = await db.query(TABLE_EMPLOYEE, where: '$COL_EMP_ID=?',whereArgs: [id]);
if(emps.length>0){
return EmployeeTeacherModel.fromMap(emps.first);
}
return null;
}
}
Here's the Model class:
final String TABLE_EMPLOYEE = "tbl_employee";
final String COL_EMP_ID = "employee_id";
final String COL_EMP_NAME = "employee_name";
final String COL_EMP_DEPARTMENT = "employee_depertment";
final String COL_EMP_PROFESSION = "employee_Student";
final String COL_EMP_DOB = "employee_DOB";
final String COL_RADIO_BUTTON = "employee_gender";
class EmployeeTeacherModel {
int id;
String name;
String depertment;
String Dob;
String profession;
int gender;
EmployeeTeacherModel({this.id, this.name, this.depertment, this.profession, this.Dob, this.gender});
Map<String,dynamic> toMap(){//method to insert data into database
var map = <String, dynamic>{//method
COL_EMP_NAME : name,
COL_EMP_PROFESSION: profession,
COL_EMP_DEPARTMENT: depertment,
COL_EMP_DOB: Dob,
COL_RADIO_BUTTON: gender,
};
if(id !=null){
map[COL_EMP_ID] = id;
}
return map;
}
EmployeeTeacherModel.fromMap(Map<String,dynamic> map){//named constructor to return emoloyee model obj
id = map[COL_EMP_ID];
name = map[COL_EMP_NAME];
profession = map[COL_EMP_PROFESSION];
depertment = map[COL_EMP_DEPARTMENT];
Dob = map[COL_EMP_DOB];
gender = map[COL_RADIO_BUTTON];
}
#override
String toString() {
return 'EmployeeTeacherModel{id: $id, name: $name, depertment: $depertment, Dob: $Dob, profession: $profession, gender: $gender}';
}
}

Read Data attributes or Custom Attributes in SQL server from string

I want in SQL prepared dynamic query based on the shortcode.
For Eg.
DECLARE #ShortCode VARCHAR(MAX)
SET #ShortCode = '[User data="Name" data="MobileNumber"]';
User = table name
Name = User table field
MobileNumber = User table field
Query output be like
SELECT [Name],[MobileNumber] FROM [dbo].[User]
SET #ShortCode = '[Country data="Name" ID="1"]';
Country = table name
Name = Country table field
ID = User table field
Query output be like
SELECT [Name] FROM [dbo].[Country] WHERE [ID] = 1
How to extract all data attributes values and how to get User in the []
This functionality is done in C#
Here My c# code
// Model class
public class ShortCodeResult
{
public Guid? ID { get; set; }
public string TableName { get; set; }
public bool IsValidShortCode { get; set; }
public string Message { get; set; }
public Dictionary<string,object> KeyValue { get; set; }
public ShortCodeResult() {
KeyValue = new Dictionary<string, object>();
ID = Guid.NewGuid();
}
}
//Regex Filter
public class RegexFilter
{
private string oPattern = #"(\w+)=[\""]([a-zA-Z0-9_.:\""]+)";
public ShortCodeResult GetShortCodeValues(string Code)
{
var oShortCodeModel = new ShortCodeResult();
var oRegex = new Regex(oPattern, RegexOptions.IgnoreCase);
var oTableNameRegex = Regex.Match(Code, #"\b[A-Za-z]+\b", RegexOptions.Singleline).Value;
var lstMatchCollection = oRegex.Matches(Code).Cast<Match>().Where(x=>x.Value.StartsWith("data")).ToList();
if (lstMatchCollection != null && lstMatchCollection.Count > 0)
{
for (int i = 0; i < lstMatchCollection.Count; i++)
{
var oSelected = new Regex("[^=]+$").Match(Convert.ToString(lstMatchCollection[i]));
if (oSelected != null)
{
oShortCodeModel.KeyValue.Add(i.ToString(), oSelected.Value.Trim('"'));
}
}
}
oShortCodeModel.TableName = oTableNameRegex;
return oShortCodeModel;
}
}
//HtmlHelper Extension
public static MvcHtmlString RenderShortCode(this HtmlHelper htmlHelper, string IdOrExprssion)
{
#region Get short code data
var oShortCode = ShortCodeHelper.GetShortCode(IdOrExprssion);
#endregion
var oMvcHtmlString = new MvcHtmlString(IdOrExprssion);
var oRegexFilter = new RegexFilter();
var shortCodeModel = oRegexFilter.GetShortCodeValues(oShortCode.Expression);
var ostringBuilder = new StringBuilder();
if (!string.IsNullOrEmpty(shortCodeModel.TableName))
{
ostringBuilder.AppendLine("SELECT ");
ostringBuilder.AppendLine((shortCodeModel.KeyValue.Count > 0 ? string.Join(",", shortCodeModel.KeyValue.Select(x => x.Value)) : "*"));
ostringBuilder.AppendLine(" FROM ");
ostringBuilder.AppendLine(oShortCode.TableName);
ostringBuilder.AppendLine(" WITH(NOLOCK) ");
if (oShortCode.FilterCode.Count() > 0)
{
ostringBuilder.AppendLine("WHERE ");
foreach (var filterCode in oShortCode.FilterCode)
{
ostringBuilder.AppendLine(filterCode.FilterColumnName);
ostringBuilder.AppendLine(filterCode.Operator);
ostringBuilder.AppendLine(filterCode.FilterColumnValue);
}
}
}
var oDyanamicData = DBHelper.GetDataTable(ostringBuilder.ToString(), System.Data.CommandType.Text, new List<SqlParameter>());
if (oDyanamicData != null)
{
if (oShortCode.IsHtmlRender)
{
for (int i = 0; i < oDyanamicData.Rows.Count; i++)
{
for (int j = 0; j < oDyanamicData.Columns.Count; j++)
{
string key = Convert.ToString(oDyanamicData.Columns[j]);
string value = Convert.ToString(oDyanamicData.Rows[i].ItemArray[j]);
if (oShortCode.DisplayCode.Count > 0)
{
var displayCode = oShortCode.DisplayCode.FirstOrDefault(x => x.DisplayColumnName == key);
if (displayCode != null && !string.IsNullOrEmpty(displayCode?.ReplaceKey))
{
oShortCode.DefinedHtml = oShortCode.DefinedHtml.Replace(displayCode.ReplaceKey, value);
}
}
}
}
return new MvcHtmlString(oShortCode.DefinedHtml);
}
else
{
string key = string.Empty, value = string.Empty;
#region For Json
List<JObject> dataList = new List<JObject>();
for (int i = 0; i < oDyanamicData.Rows.Count; i++)
{
JObject eachRowObj = new JObject();
for (int j = 0; j < oDyanamicData.Columns.Count; j++)
{
key = Convert.ToString(oDyanamicData.Columns[j]);
value = Convert.ToString(oDyanamicData.Rows[i].ItemArray[j]);
eachRowObj.Add(key, value);
}
dataList.Add(eachRowObj);
}
return new MvcHtmlString(Newtonsoft.Json.JsonConvert.SerializeObject(dataList));
#endregion
}
}
return oMvcHtmlString;
}
Can anyone help me solved above in SQL server or prepared query in store procedure

Rhino Mock and Method Not Returning Correct Value

Does anyone know why UsernameExists wont return True. I must have my syntax messed up somewhere.
[TestMethod()]
public void GenerateUsername_AppendTwoCharacters_ReturnUsernameWithTwoAppendedCharacters()
{
var usersRepository = MockRepository.GenerateStub<IUsersRepository>();
var target = new StudentsService(null, null, usersRepository, null, null, null, null);
usersRepository.Expect(q => q.UsernameExists("", null)).Return(true);
var actual = target.GenerateUsername("test", "student", "280000");
Assert.AreEqual("A", actual);
}
public string GenerateUsername(string firstName, string lastName, string studentNumber)
{
var originalusername = new StudentUsernameGenerator(firstName, lastName, studentNumber).Generate(2, 2, 4);
var username = originalusername;
if (!string.IsNullOrWhiteSpace(username))
{
decimal maxCharacters = 26;
var counter = 0;
var overflow = 1;
while (_usersRepository.UsernameExists(username, null))
{
counter++;
if (counter > maxCharacters)
{
overflow++;
counter = 1;
}
username = GetCharacterPaddingForDuplicateUsername(counter, overflow, originalusername);
}
}
return username;
}
I had to add IgnoreArguments
usersRepository.Stub(q => q.UsernameExists("", null)).IgnoreArguments().Return(true);