Beispiel #1
0
        public FFFile(FFApp app, FFDatabase db, SQLiteDataReader fileRdr)
        {
#if DEBUG
            if (app == null)
            {
                throw new ArgumentNullException("app");
            }
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }
            if (fileRdr == null)
            {
                throw new ArgumentNullException("rdr");
            }
#endif
            _app      = app;
            _id       = fileRdr.GetInt64(fileRdr.GetOrdinal("rowid"));
            _fileName = fileRdr.GetString(fileRdr.GetOrdinal("file_name"));
            _context  = FileContextUtil.GetFileContextFromFileName(_fileName);
            _modified = fileRdr.GetDateTime(fileRdr.GetOrdinal("modified"));

            var className = FileContextUtil.GetClassNameFromFileName(_fileName);
            if (!string.IsNullOrEmpty(className))
            {
                _class = new FFClass(_app, this, className);
            }

            UpdateVisibility();
        }
Beispiel #2
0
        public void InsertOrUpdate(FFDatabase db, CodeModel.FileStore store, CodeModel.CodeModel model)
        {
            if (_id != 0)
            {
                using (var cmd = db.CreateCommand("update file_ set modified = @modified, visible = @visible where rowid = @id"))
                {
                    cmd.Parameters.AddWithValue("@id", _id);
                    cmd.Parameters.AddWithValue("@modified", _modified);
                    cmd.Parameters.AddWithValue("@visible", _visible ? 1 : 0);
                    cmd.ExecuteNonQuery();
                }
            }
            else
            {
                using (var cmd = db.CreateCommand(
                           "insert into file_ (app_id, file_name, modified, visible) values (@app_id, @file_name, @modified, @visible);"
                           + " select last_insert_rowid();"))
                {
                    cmd.Parameters.AddWithValue("@app_id", _app.Id);
                    cmd.Parameters.AddWithValue("@file_name", _fileName);
                    cmd.Parameters.AddWithValue("@modified", _modified);
                    cmd.Parameters.AddWithValue("@visible", _visible ? 1 : 0);
                    _id = Convert.ToInt64(cmd.ExecuteScalar());
                }
            }

            UpdateIncludeDependencies(db, store, model);
        }
Beispiel #3
0
        private void LoadCurrentApp()
        {
            try
            {
                if (!_appSettings.Initialized)
                {
                    return;
                }

                Log.Write(LogLevel.Info, "Loading function file database...");
                var startTime = DateTime.Now;

                using (var db = new FFDatabase())
                {
                    _currentApp = new FFApp(this, db, _appSettings);
                }

                var elapsed = DateTime.Now.Subtract(startTime);
                Log.Write(LogLevel.Info, "Function file database loaded. (elapsed: {0})", elapsed);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error when loading function file database.");
                _currentApp = null;
            }
        }
Beispiel #4
0
        private void UpdatePermExList(FFDatabase db, IEnumerable <CodeModel.Tokens.Statements.ExtractStatement> exList)
        {
            var keptPermExs = new List <FFPermEx>();

            foreach (var extract in exList)
            {
                FFPermEx permEx = _permExs.FirstOrDefault(p => p.Name == extract.Name);
                if (permEx != null)
                {
                    permEx.UpdateFromToken(extract);
                }
                else
                {
                    var token = extract.FindFirstChild <ExtractTableToken>();
                    if (token == null)
                    {
                        continue;
                    }

                    var def = token.SourceDefinition as ExtractTableDefinition;
                    if (def == null)
                    {
                        continue;
                    }

                    permEx = new FFPermEx(this, extract, def);
                    _permExs.Add(permEx);
                }

                permEx.SyncToDatabase(db);
                keptPermExs.Add(permEx);
            }

            // Remove deleted extracts
            var exsToDelete = _permExs.Where(p => !keptPermExs.Any(k => k.Name == p.Name)).ToArray();

            if (exsToDelete.Length > 0)
            {
                using (var cmd = db.CreateCommand("delete from permex_col where permex_id = @permex_id"))
                {
                    foreach (var permex in exsToDelete)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@permex_id", permex.Id);
                        cmd.ExecuteNonQuery();
                    }
                }

                using (var cmd = db.CreateCommand("delete from permex where rowid = @id"))
                {
                    foreach (var permex in exsToDelete)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@id", permex.Id);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
Beispiel #5
0
 public void Dispose()
 {
     if (_db != null)
     {
         _db.Dispose();
         _db = null;
     }
 }
Beispiel #6
0
        private void PurgeNonexistentApps(FFDatabase db)
        {
            var appsToRemove = new Dictionary <long, string>();
            var appNames     = _appSettings.AllAppNames.ToArray();

            using (var cmd = db.CreateCommand("select rowid, name from app"))
            {
                using (var rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        var name = rdr.GetString(1);
                        if (!appNames.Any(a => string.Equals(a, name, StringComparison.OrdinalIgnoreCase)))
                        {
                            appsToRemove[rdr.GetInt64(0)] = name;
                        }
                    }
                }
            }

            foreach (var appId in appsToRemove.Keys)
            {
                Log.Write(LogLevel.Info, "Removing app {0} from database because it no longer exists in the DK environment.", appsToRemove[appId]);

                using (var cmd = db.CreateCommand("delete from func where app_id = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", appId);
                    cmd.ExecuteNonQuery();
                }

                using (var cmd = db.CreateCommand("delete from include_depends where app_id = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", appId);
                    cmd.ExecuteNonQuery();
                }

                using (var cmd = db.CreateCommand("delete from ref where app_id = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", appId);
                    cmd.ExecuteNonQuery();
                }

                using (var cmd = db.CreateCommand("delete from file_ where app_id = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", appId);
                    cmd.ExecuteNonQuery();
                }

                using (var cmd = db.CreateCommand("delete from app where rowid = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", appId);
                    cmd.ExecuteNonQuery();
                }
            }
        }
Beispiel #7
0
 public void Remove(FFDatabase db)
 {
     if (_id != 0)
     {
         using (var cmd = db.CreateCommand("delete from func where rowid = @id"))
         {
             cmd.Parameters.AddWithValue("@id", _id);
             cmd.ExecuteNonQuery();
         }
     }
 }
Beispiel #8
0
        public void Load(FFDatabase db)
        {
            _fields.Clear();

            using (var cmd = db.CreateCommand(@"
				select name, pos, data_type, alt_file.file_name as alt_file_name from permex_col
				left outer join alt_file on alt_file.rowid = permex_col.alt_file_id
				where permex_id = @id
				"                ))
            {
                cmd.Parameters.AddWithValue("@id", _id);

                using (var rdr = cmd.ExecuteReader())
                {
                    var ordName        = rdr.GetOrdinal("name");
                    var ordAltFileName = rdr.GetOrdinal("alt_file_name");
                    var ordPos         = rdr.GetOrdinal("pos");
                    var ordDataType    = rdr.GetOrdinal("data_type");

                    while (rdr.Read())
                    {
                        var name = rdr.GetString(ordName);

                        var fileName = rdr.GetStringOrNull(ordAltFileName);
                        if (string.IsNullOrEmpty(fileName))
                        {
                            fileName = _file.FileName;
                        }
                        var pos     = rdr.GetInt32(ordPos);
                        var filePos = new FilePosition(fileName, pos);

                        var fieldDef = new ExtractFieldDefinition(name, filePos, _def);
                        _fields.Add(fieldDef);
                        _def.AddField(fieldDef);

                        var dataTypeString = rdr.GetString(ordDataType);
                        if (!string.IsNullOrEmpty(dataTypeString))
                        {
                            var dataType = DataType.TryParse(new DataType.ParseArgs {
                                Code = new CodeParser(dataTypeString)
                            });
                            if (dataType == null)
                            {
                                Log.Debug("Failed to parse permanent extract data type from database: {0}", dataTypeString);
                                dataType = new CodeModel.DataType(ValType.Unknown, null,
                                                                  new Classifier.ProbeClassifiedString(Classifier.ProbeClassifierType.DataType, dataTypeString));
                            }
                            fieldDef.SetDataType(dataType);
                        }
                    }
                }
            }
        }
Beispiel #9
0
        public long GetAltFileId(FFDatabase db, string fileName)
        {
            using (var cmd = db.CreateCommand("select rowid from alt_file where file_name = @file_name limit 1"))
            {
                cmd.Parameters.AddWithValue("@file_name", fileName);
                using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                {
                    if (rdr.Read())
                    {
                        return(rdr.GetInt64(0));
                    }
                }
            }

            return(0L);
        }
Beispiel #10
0
        private void ProcessQueue()
        {
            if (_currentApp == null)
            {
                return;
            }

            using (var db = new FFDatabase())
            {
                var scanStartTime = DateTime.Now;

                while (!_kill.WaitOne(k_threadWaitActive))
                {
                    ScanInfo?scanInfo = null;
                    lock (_scanLock)
                    {
                        if (_scanQueue != null && _scanQueue.Count > 0)
                        {
                            scanInfo = _scanQueue.Dequeue();
                        }
                    }

                    if (scanInfo.HasValue)
                    {
                        ProcessFile(db, CurrentApp, scanInfo.Value);
                    }
                    else
                    {
                        ProbeToolsPackage.Instance.SetStatusText("DkTools background purging...");
                        using (var txn = db.BeginTransaction())
                        {
                            _currentApp.PurgeData(db);
                            txn.Commit();
                        }

                        var scanElapsed = DateTime.Now.Subtract(scanStartTime);

                        ProbeToolsPackage.Instance.SetStatusText(string.Format("DkTools background scanning complete.  (elapsed: {0})", scanElapsed));
                        lock (_scanLock)
                        {
                            _scanQueue = null;
                        }
                        return;
                    }
                }
            }
        }
Beispiel #11
0
        public long GetOrCreateAltFileId(FFDatabase db, string fileName)
        {
            using (var cmd = db.CreateCommand("select rowid from alt_file where file_name = @file_name limit 1"))
            {
                cmd.Parameters.AddWithValue("@file_name", fileName);
                using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                {
                    if (rdr.Read())
                    {
                        return(rdr.GetInt64(0));
                    }
                }
            }

            using (var cmd = db.CreateCommand("insert into alt_file (file_name) values (@file_name); select last_insert_rowid();"))
            {
                cmd.Parameters.AddWithValue("@file_name", fileName);
                return(Convert.ToInt64(cmd.ExecuteScalar()));
            }
        }
Beispiel #12
0
        public FFFile GetFileForScan(FFDatabase db, string fileName)
        {
            FFFile file;
            var    fileNameLower = fileName.ToLower();

            lock (_files)
            {
                if (_files.TryGetValue(fileNameLower, out file))
                {
                    return(file);
                }
            }

            // Check if this is in the list of invisible files.
            if (_invisibleFiles.ContainsKey(fileNameLower))
            {
                using (var cmd = db.CreateCommand("select rowid, * from file_ where app_id = @app_id and file_name = @file_name"))
                {
                    cmd.Parameters.AddWithValue("@app_id", _id);
                    cmd.Parameters.AddWithValue("@file_name", fileName);
                    using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                    {
                        if (rdr.Read())
                        {
                            file = new FFFile(this, db, rdr);
                        }
                    }
                }
            }

            if (file != null)
            {
                // Was loaded as invisible file
                file.Load(db);
                return(file);
            }

            // New file
            file = new FFFile(this, fileName);
            return(file);
        }
Beispiel #13
0
        public void Load(FFDatabase db)
        {
            using (var cmd = db.CreateCommand(
                       "select func.rowid, func.*, alt_file.file_name as alt_file_name from func" +
                       " left outer join alt_file on alt_file.rowid = func.alt_file_id" +
                       " where file_id = @file_id"))
            {
                cmd.Parameters.AddWithValue("@file_id", _id);
                using (var funcRdr = cmd.ExecuteReader())
                {
                    while (funcRdr.Read())
                    {
                        _functions.Add(new FFFunction(_app, this, _class, funcRdr));
                    }
                }
            }

            using (var cmd = db.CreateCommand(
                       "select permex.rowid, permex.*, alt_file.file_name as alt_file_name from permex" +
                       " left outer join alt_file on alt_file.rowid = permex.alt_file_id" +
                       " where permex.file_id = @file_id"))
            {
                cmd.Parameters.AddWithValue("@file_id", _id);
                using (var rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        _permExs.Add(new FFPermEx(this, rdr));
                    }
                }
            }

            foreach (var permex in _permExs)
            {
                permex.Load(db);
            }
        }
Beispiel #14
0
 public FFSearcher(FFApp app)
 {
     _app = app;
     _db  = new FFDatabase();
 }
Beispiel #15
0
        private void UpdateIncludeDependencies(FFDatabase db, CodeModel.FileStore store, CodeModel.CodeModel model)
        {
            var modelIncludeList = model.PreprocessorModel.IncludeDependencies.ToArray();

            var dbIncludes = new List <DbInclude>();

            using (var cmd = db.CreateCommand("select rowid, include_file_name, include, localized_file from include_depends where file_id = @file_id"))
            {
                cmd.Parameters.AddWithValue("@file_id", _id);
                using (var rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        dbIncludes.Add(new DbInclude
                        {
                            id            = rdr.GetInt64(0),
                            fileName      = rdr.GetString(1),
                            include       = rdr.GetTinyIntBoolean(2),
                            localizedFile = rdr.GetTinyIntBoolean(3)
                        });
                    }
                }
            }

            // Remove dependencies that are no longer there
            var recordsToRemove = (from d in dbIncludes
                                   where !modelIncludeList.Any(m => m.FileName.Equals(d.fileName, StringComparison.OrdinalIgnoreCase) &&
                                                               m.Include == d.include &&
                                                               m.LocalizedFile == d.localizedFile)
                                   select d).ToArray();

            if (recordsToRemove.Length > 0)
            {
                using (var cmd = db.CreateCommand("delete from include_depends where rowid = @rowid"))
                {
                    foreach (var id in recordsToRemove)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@rowid", id);
                        cmd.ExecuteNonQuery();
                    }
                }
            }

            // Add new dependencies
            var recordsToAdd = (from m in modelIncludeList
                                where !dbIncludes.Any(d => d.fileName.Equals(m.FileName, StringComparison.OrdinalIgnoreCase) &&
                                                      d.include == m.Include &&
                                                      d.localizedFile == m.LocalizedFile)
                                select m).ToArray();

            if (recordsToAdd.Length > 0)
            {
                using (var cmd = db.CreateCommand(@"
					insert into include_depends (app_id, file_id, include_file_name, include, localized_file)
					values (@app_id, @file_id, @include_file_name, @include, @localized_file)
					"                    ))
                {
                    foreach (var incl in recordsToAdd)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@app_id", _app.Id);
                        cmd.Parameters.AddWithValue("@file_id", _id);
                        cmd.Parameters.AddWithValue("@include_file_name", incl.FileName);
                        cmd.Parameters.AddWithValue("@include", incl.Include ? 1 : 0);
                        cmd.Parameters.AddWithValue("@localized_file", incl.LocalizedFile ? 1 : 0);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
Beispiel #16
0
        public void PurgeData(FFDatabase db)
        {
            // Remove files in memory that don't exist on disk.
            {
                var removeFiles = new List <FFFile>();

                foreach (var file in _files.Values)
                {
                    if (!File.Exists(file.FileName))
                    {
                        removeFiles.Add(file);
                    }
                }

                foreach (var removeFile in removeFiles)
                {
                    _files.Remove(removeFile.FileName.ToLower());
                    removeFile.Remove(db);
                }
            }

            // Remove files in the database that aren't in memory.
            {
                var removeFiles = new List <long>();

                using (var cmd = db.CreateCommand("select rowid, file_name from file_ where app_id = @app_id"))
                {
                    cmd.Parameters.AddWithValue("@app_id", _id);
                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            var id            = rdr.GetInt64(0);
                            var fileNameLower = rdr.GetString(1).ToLower();

                            if (!_files.ContainsKey(fileNameLower) &&
                                !_invisibleFiles.ContainsKey(fileNameLower))
                            {
                                removeFiles.Add(id);
                            }
                        }
                    }
                }

                foreach (var id in removeFiles)
                {
                    using (var cmd = db.CreateCommand("delete from file_ where rowid = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }

                    using (var cmd = db.CreateCommand("delete from func where file_id = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }

                    using (var cmd = db.CreateCommand("delete from ref where file_id = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }

                    using (var cmd = db.CreateCommand("delete from include_depends where file_id = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }

                    using (var cmd = db.CreateCommand("delete from permex_col where file_id = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }

                    using (var cmd = db.CreateCommand("delete from permex where file_id = @id"))
                    {
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }
                }
            }

            // Purge alt_file records that are no longer used

            List <long> altFilesToRemove = null;

            using (var cmd = db.CreateCommand("select rowid from alt_file" +
                                              " where not exists (select * from func where alt_file_id = alt_file.rowid)" +
                                              " and not exists (select * from ref where alt_file_id = alt_file.rowid)" +
                                              " and not exists (select * from permex where alt_file_id = alt_file.rowid)" +
                                              " and not exists (select * from permex_col where alt_file_id = alt_file.rowid)"))
            {
                using (var rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        if (altFilesToRemove == null)
                        {
                            altFilesToRemove = new List <long>();
                        }
                        altFilesToRemove.Add(rdr.GetInt64(0));
                    }
                }
            }

            if (altFilesToRemove != null)
            {
                using (var cmd = db.CreateCommand("delete from alt_file where rowid = @id"))
                {
                    foreach (var id in altFilesToRemove)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }
                }
            }

            PurgeNonexistentApps(db);
        }
Beispiel #17
0
        public FFApp(FFScanner scanner, FFDatabase db, ProbeAppSettings appSettings)
        {
            _scanner     = scanner ?? throw new ArgumentNullException(nameof(scanner));
            _appSettings = appSettings ?? throw new ArgumentNullException(nameof(appSettings));

            if (!_appSettings.Initialized)
            {
                return;
            }

            var conn = db.Connection;

            if (conn == null)
            {
                return;
            }

            // Load app info
            using (var cmd = db.CreateCommand("select rowid from app where name = @name"))
            {
                cmd.Parameters.AddWithValue("@name", _appSettings.AppName);
                using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                {
                    if (rdr.Read())
                    {
                        _id = rdr.GetInt64(0);
                    }
                }
            }

            if (_id != 0)
            {
                // Load files
                var loadedFiles = new List <FFFile>();
                using (var cmd = db.CreateCommand("select rowid, * from file_ where app_id = @app_id and visible != 0"))
                {
                    cmd.Parameters.AddWithValue("@app_id", _id);
                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            loadedFiles.Add(new FFFile(this, db, rdr));
                        }
                    }
                }

                foreach (var file in loadedFiles)
                {
                    file.Load(db);
                    _files[file.FileName.ToLower()] = file;
                }

                using (var cmd = db.CreateCommand("select file_name, modified from file_ where app_id = @app_id and visible = 0"))
                {
                    cmd.Parameters.AddWithValue("@app_id", _id);
                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            var fileName = rdr.GetString(0);
                            var modified = rdr.GetDateTime(1);
                            _invisibleFiles[fileName.ToLower()] = modified;
                        }
                    }
                }
            }
            else             // _id == 0
            {
                using (var cmd = db.CreateCommand("insert into app (name) values (@name); select last_insert_rowid();"))
                {
                    cmd.Parameters.AddWithValue("@name", _appSettings.AppName);
                    _id = Convert.ToInt64(cmd.ExecuteScalar());
                }

                var options = ProbeToolsPackage.Instance.EditorOptions;
                if (!options.DisableBackgroundScan)
                {
                    Shell.ShowNotificationAsync(Res.FFDatabaseCreationNotification, Res.FFDatabaseCreationCaption);
                }
            }
        }
Beispiel #18
0
        private void UpdateRefList(FFDatabase db, List <Reference> refList)
        {
            // Initialize the flags on each ref
            var memRefs = new List <Reference>();

            memRefs.AddRange(refList);
            foreach (var r in memRefs)
            {
                r.Exists = false;
            }

            List <long> dbRefsToRemove = null;

            // Scan the refs in the database to find which ones should be updated or removed
            using (var cmd = db.CreateCommand("select ref.rowid, ref.*, alt_file.file_name as true_file_name from ref "
                                              + "left outer join alt_file on alt_file.rowid = ref.alt_file_id "
                                              + "where file_id = @file_id"))
            {
                cmd.Parameters.AddWithValue("@file_id", _id);

                using (var rdr = cmd.ExecuteReader())
                {
                    var ordId           = rdr.GetOrdinal("rowid");
                    var ordExtRefId     = rdr.GetOrdinal("ext_ref_id");
                    var ordTrueFileName = rdr.GetOrdinal("true_file_name");
                    var ordPos          = rdr.GetOrdinal("pos");

                    while (rdr.Read())
                    {
                        var id           = rdr.GetInt64(ordId);
                        var extRefId     = rdr.GetString(ordExtRefId);
                        var trueFileName = rdr.GetStringOrNull(ordTrueFileName);
                        var pos          = rdr.GetInt32(ordPos);

                        var memRef = memRefs.FirstOrDefault(r => r.ExternalRefId == extRefId &&
                                                            (r.TrueFileName == null) == (trueFileName == null) &&
                                                            (r.TrueFileName == null || string.Equals(r.TrueFileName, trueFileName, StringComparison.OrdinalIgnoreCase)) &&
                                                            r.Position == pos);
                        if (memRef != null)
                        {
                            memRef.Exists = true;
                        }
                        else
                        {
                            if (dbRefsToRemove == null)
                            {
                                dbRefsToRemove = new List <long>();
                            }
                            dbRefsToRemove.Add(id);
                        }
                    }
                }
            }

            // Remove refs no longer used
            if (dbRefsToRemove != null)
            {
                using (var cmd = db.CreateCommand("delete from ref where rowid = @id"))
                {
                    foreach (var id in dbRefsToRemove)
                    {
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@id", id);
                        cmd.ExecuteNonQuery();
                    }
                }
            }

            // Insert new refs
            if (memRefs.Any(r => !r.Exists))
            {
                // Get the list of alt file names used.
                var altFileNames = new Dictionary <string, long>();
                foreach (var altFileName in (from r in memRefs where !r.Exists && !string.IsNullOrEmpty(r.TrueFileName) select r.TrueFileName))
                {
                    if (!altFileNames.Keys.Any(x => string.Equals(x, altFileName)))
                    {
                        altFileNames[altFileName] = 0;
                    }
                }

                if (altFileNames.Any())
                {
                    // Look up the IDs of any alt file names used.
                    using (var cmd = db.CreateCommand("select rowid from alt_file where file_name = @file_name limit 1"))
                    {
                        foreach (var altFileName in altFileNames.Keys.ToArray())                                // Put into array early to avoid collection modified error
                        {
                            cmd.Parameters.Clear();
                            cmd.Parameters.AddWithValue("@file_name", altFileName);

                            using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                            {
                                if (rdr.Read())
                                {
                                    altFileNames[altFileName] = rdr.GetInt64(0);
                                }
                            }
                        }
                    }

                    // Insert new alt file names.
                    if (altFileNames.Any(x => x.Value == 0))
                    {
                        using (var cmd = db.CreateCommand("insert into alt_file (file_name) values (@file_name); select last_insert_rowid();"))
                        {
                            foreach (var altFileName in (from a in altFileNames where a.Value == 0 select a.Key).ToArray())                             // Put into array early to avoid collection modified error
                            {
                                cmd.Parameters.Clear();
                                cmd.Parameters.AddWithValue("@file_name", altFileName);
                                altFileNames[altFileName] = Convert.ToInt64(cmd.ExecuteScalar());
                            }
                        }
                    }
                }

                // Inserts the ref records
                using (var cmd = db.CreateCommand("insert into ref (app_id, file_id, ext_ref_id, alt_file_id, pos)" +
                                                  " values (@app_id, @file_id, @ext_ref_id, @alt_file_id, @pos)"))
                {
                    foreach (var newRef in memRefs.Where(r => !r.Exists))
                    {
                        var trueFileId = 0L;
                        if (!string.IsNullOrEmpty(newRef.TrueFileName))
                        {
                            var altFileName = (from a in altFileNames where string.Equals(a.Key, newRef.TrueFileName, StringComparison.OrdinalIgnoreCase) select a.Key).FirstOrDefault();
                            if (altFileName != null)
                            {
                                trueFileId = altFileNames[altFileName];
                            }
                        }

                        cmd.Parameters.Clear();
                        cmd.Parameters.AddWithValue("@app_id", _app.Id);
                        cmd.Parameters.AddWithValue("@file_id", _id);
                        cmd.Parameters.AddWithValue("@ext_ref_id", newRef.ExternalRefId);
                        cmd.Parameters.AddWithValue("@alt_file_id", trueFileId);
                        cmd.Parameters.AddWithValue("@pos", newRef.Position);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
Beispiel #19
0
        public void UpdateFromModel(CodeModel.CodeModel model, FFDatabase db, FileStore store, DateTime fileModified, FFScanMode scanMode)
        {
            if (scanMode == FFScanMode.Deep)
            {
                _modified = fileModified;
            }
            else
            {
                _modified = Constants.ZeroDate;
            }
            UpdateVisibility();
            InsertOrUpdate(db, store, model);

            // Only extract functions for .f files or class files.
            switch (_context)
            {
            case CodeModel.FileContext.Function:
            case CodeModel.FileContext.ClientClass:
            case CodeModel.FileContext.ServerClass:
            case CodeModel.FileContext.NeutralClass:

                // Get the list of functions defined in the file.
                var modelFuncs = (from f in model.DefinitionProvider.GetGlobalFromFile <CodeModel.Definitions.FunctionDefinition>()
                                  where f.Extern == false
                                  select f).ToArray();

                // Insert/update the functions that exist in the model.
                foreach (var modelFunc in modelFuncs)
                {
                    var func = _functions.FirstOrDefault(f => f.Name == modelFunc.Name);
                    if (func != null)
                    {
                        func.UpdateFromDefinition(modelFunc);
                    }
                    else
                    {
                        func = new FFFunction(_app, this, _class, modelFunc);
                        _functions.Add(func);
                    }

                    func.InsertOrUpdate(db);
                }

                // Purge functions that no longer exist in the model.
                var removeFuncs = (from f in _functions where !modelFuncs.Any(m => m.Name == f.Name) select f).ToArray();
                foreach (var removeFunc in removeFuncs)
                {
                    removeFunc.Remove(db);
                    _functions.Remove(removeFunc);
                }

                break;
            }

            // Get all permanent extracts in the file
            UpdatePermExList(db, model.File.FindDownward <CodeModel.Tokens.Statements.ExtractStatement>().Where(x => x.IsPermanent).ToArray());

            if (scanMode == FFScanMode.Deep)
            {
                // Get all references in the file.
                var refList = new List <Reference>();
                foreach (var token in model.File.FindDownward(t => t.SourceDefinition != null &&
                                                              !string.IsNullOrEmpty(t.SourceDefinition.ExternalRefId) &&
                                                              t.File != null))
                {
                    var localPos = token.File.CodeSource.GetFilePosition(token.Span.Start);

                    var def   = token.SourceDefinition;
                    var refId = def.ExternalRefId;
                    if (!string.IsNullOrEmpty(refId))
                    {
                        refList.Add(new Reference
                        {
                            ExternalRefId = refId,
                            TrueFileName  = string.Equals(localPos.FileName, model.FileName, StringComparison.OrdinalIgnoreCase) ? null : localPos.FileName,
                            Position      = localPos.Position
                        });
                    }
                }

                foreach (var rf in model.PreprocessorReferences)
                {
                    var def   = rf.Definition;
                    var refId = def.ExternalRefId;
                    if (!string.IsNullOrEmpty(refId))
                    {
                        var filePos = rf.FilePosition;
                        if (filePos.PrimaryFile)
                        {
                            refList.Add(new Reference
                            {
                                ExternalRefId = refId,
                                TrueFileName  = filePos.FileName,
                                Position      = filePos.Position
                            });
                        }
                    }
                }

                UpdateRefList(db, refList);
            }
        }
Beispiel #20
0
        private void ProcessFile(FFDatabase db, FFApp app, ScanInfo scan)
        {
            try
            {
                if (!File.Exists(scan.fileName))
                {
                    return;
                }
                if (FileContextUtil.IsLocalizedFile(scan.fileName))
                {
                    return;
                }

                var fileContext = CodeModel.FileContextUtil.GetFileContextFromFileName(scan.fileName);
                if (fileContext == FileContext.Include)
                {
                    return;
                }

                DateTime modified;
                if (!app.TryGetFileDate(scan.fileName, out modified))
                {
                    modified = DateTime.MinValue;
                }

                var fileModified = File.GetLastWriteTime(scan.fileName);
                if (!scan.forceScan)
                {
                    if (modified != DateTime.MinValue && fileModified.Subtract(modified).TotalSeconds < 1.0)
                    {
                        return;
                    }
                }

                var ffFile = app.GetFileForScan(db, scan.fileName);

                Log.Debug("Processing file: {0} (modified={1}, last modified={2})", scan.fileName, fileModified, modified);
                if (scan.mode == FFScanMode.Exports)
                {
                    ProbeToolsPackage.Instance.SetStatusText(string.Format("DkTools background scanning file: {0} (exports only)", scan.fileName));
                }
                else
                {
                    ProbeToolsPackage.Instance.SetStatusText(string.Format("DkTools background scanning file: {0}", scan.fileName));
                }

                var fileTitle = Path.GetFileNameWithoutExtension(scan.fileName);

                var defProvider = new CodeModel.DefinitionProvider(_appSettings, scan.fileName);

                var fileContent = File.ReadAllText(scan.fileName);
                var fileStore   = new CodeModel.FileStore();

                var merger = new FileMerger();
                merger.MergeFile(_appSettings, scan.fileName, null, false, true);
                var includeDependencies = (from f in merger.FileNames
                                           select new Preprocessor.IncludeDependency(f, false, true, merger.GetFileContent(f))).ToArray();

                var model = fileStore.CreatePreprocessedModel(_appSettings, merger.MergedContent, scan.fileName, false, string.Concat("Function file processing: ", scan.fileName), includeDependencies);

                var className = fileContext.IsClass() ? Path.GetFileNameWithoutExtension(scan.fileName) : null;
                var classList = new List <FFClass>();
                var funcList  = new List <FFFunction>();

                using (var txn = db.BeginTransaction())
                {
                    ffFile.UpdateFromModel(model, db, fileStore, fileModified, scan.mode);
                    txn.Commit();
                }

                if (ffFile.Visible)
                {
                    app.OnVisibleFileChanged(ffFile);
                }
                else
                {
                    app.OnInvisibleFileChanged(ffFile);
                }

#if DEBUG
                FFDatabase.DumpMemoryStats();
#endif
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Exception when background processing function name: {0} (mode: {1})", scan.fileName, scan.mode);
            }
        }
Beispiel #21
0
        public void SyncToDatabase(FFDatabase db)
        {
            long trueFileId = string.Equals(_filePos.FileName, _file.FileName, StringComparison.OrdinalIgnoreCase) ? 0L :
                              _file.App.GetOrCreateAltFileId(db, _filePos.FileName);

            if (_id == 0)
            {
                // Insert the master record
                using (var cmd = db.CreateCommand(@"
					insert into permex (app_id, file_id, name, alt_file_id, pos)
					values (@app_id, @file_id, @name, @alt_file_id, @pos);
					select last_insert_rowid()
					"                    ))
                {
                    cmd.Parameters.AddWithValue("@app_id", _file.App.Id);
                    cmd.Parameters.AddWithValue("@file_id", _file.Id);
                    cmd.Parameters.AddWithValue("@name", _name);
                    cmd.Parameters.AddWithValue("@alt_file_id", trueFileId);
                    cmd.Parameters.AddWithValue("@pos", _filePos.Position);
                    _id = Convert.ToInt64(cmd.ExecuteScalar());
                }

                // Insert all the fields
                foreach (var field in _fields)
                {
                    var fieldFilePos    = field.FilePosition;
                    var fieldTrueFileId = string.Equals(fieldFilePos.FileName, _file.FileName, StringComparison.OrdinalIgnoreCase) ? 0 :
                                          _file.App.GetOrCreateAltFileId(db, fieldFilePos.FileName);
                    var fieldDataType = field.DataType != null?field.DataType.ToCodeString() : string.Empty;

                    using (var cmd = db.CreateCommand(@"
						insert into permex_col (permex_id, file_id, name, data_type, alt_file_id, pos)
						values (@permex_id, @file_id, @name, @data_type, @alt_file_id, @pos)
						"                        ))
                    {
                        cmd.Parameters.AddWithValue("@permex_id", _id);
                        cmd.Parameters.AddWithValue("@file_id", _file.Id);
                        cmd.Parameters.AddWithValue("@name", field.Name);
                        cmd.Parameters.AddWithValue("@data_type", fieldDataType);
                        cmd.Parameters.AddWithValue("@alt_file_id", fieldTrueFileId);
                        cmd.Parameters.AddWithValue("@pos", fieldFilePos.Position);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            else
            {
                // Update the master record
                using (var cmd = db.CreateCommand("update permex set alt_file_id = @alt_file_id, pos = @pos where rowid = @id"))
                {
                    cmd.Parameters.AddWithValue("@id", _id);
                    cmd.Parameters.AddWithValue("@alt_file_id", trueFileId);
                    cmd.Parameters.AddWithValue("@pos", _filePos.Position);
                }

                // Get a list of fields under this extract
                var dbNames = new Dictionary <string, long>();
                using (var cmd = db.CreateCommand("select rowid, name from permex_col where permex_id = @permex_id"))
                {
                    cmd.Parameters.AddWithValue("@permex_id", _id);
                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            var id   = rdr.GetInt64(0);
                            var name = rdr.GetString(1);
                            dbNames[name] = id;
                        }
                    }
                }

                // Sync the fields under this record
                foreach (var field in _fields)
                {
                    var fieldFilePos    = field.FilePosition;
                    var fieldTrueFileId = string.Equals(fieldFilePos.FileName, _file.FileName, StringComparison.OrdinalIgnoreCase) ? 0 :
                                          _file.App.GetOrCreateAltFileId(db, fieldFilePos.FileName);
                    var fieldDataType = field.DataType != null?field.DataType.ToCodeString() : string.Empty;

                    if (dbNames.ContainsKey(field.Name))
                    {
                        // Field already exists in the database, so update it
                        using (var cmd = db.CreateCommand(@"
							update permex_col set
							data_type = @data_type,
							alt_file_id = @alt_file_id,
							pos = @pos
							where rowid = @id
							"                            ))
                        {
                            cmd.Parameters.AddWithValue("@id", dbNames[field.Name]);
                            cmd.Parameters.AddWithValue("@data_type", fieldDataType);
                            cmd.Parameters.AddWithValue("@alt_file_id", fieldTrueFileId);
                            cmd.Parameters.AddWithValue("@pos", fieldFilePos.Position);
                            cmd.ExecuteNonQuery();
                        }
                    }
                    else
                    {
                        // Field does not yet exist in the database, so insert a new one
                        using (var cmd = db.CreateCommand(@"
							insert into permex_col (permex_id, file_id, name, data_type, alt_file_id, pos)
							values (@permex_id, @file_id, @name, @data_type, @alt_file_id, @pos)
							"                            ))
                        {
                            cmd.Parameters.AddWithValue("@permex_id", _id);
                            cmd.Parameters.AddWithValue("@file_id", _file.Id);
                            cmd.Parameters.AddWithValue("@name", field.Name);
                            cmd.Parameters.AddWithValue("@data_type", fieldDataType);
                            cmd.Parameters.AddWithValue("@alt_file_id", fieldTrueFileId);
                            cmd.Parameters.AddWithValue("@pos", fieldFilePos.Position);
                            cmd.ExecuteNonQuery();
                        }
                    }
                }

                // Check for fields that no longer exist and need to be deleted from the database
                var fieldIdsToDelete = (from d in dbNames where !_fields.Any(f => d.Key == f.Name) select d.Value).ToArray();
                if (fieldIdsToDelete.Length > 0)
                {
                    using (var cmd = db.CreateCommand("delete from permex_col where rowid = @id"))
                    {
                        foreach (var fieldId in fieldIdsToDelete)
                        {
                            cmd.Parameters.Clear();
                            cmd.Parameters.AddWithValue("@id", fieldId);
                            cmd.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
Beispiel #22
0
        private void EnqueueFilesDependentOnInclude(string includeFileName)
        {
            if (_currentApp == null)
            {
                return;
            }

            var options = ProbeToolsPackage.Instance.EditorOptions;

            if (options.DisableBackgroundScan)
            {
                return;
            }

            using (var db = new FFDatabase())
            {
                var fileIds = new Dictionary <long, string>();

                using (var cmd = db.CreateCommand(@"
					select file_id, file_name from include_depends
					inner join file_ on file_.rowid = include_depends.file_id
					where include_depends.app_id = @app_id
					and include_depends.include_file_name = @include_file_name
					"                    ))
                {
                    cmd.Parameters.AddWithValue("@app_id", _currentApp.Id);
                    cmd.Parameters.AddWithValue("@include_file_name", includeFileName);

                    using (var rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            var fileName = rdr.GetString(1);
                            var context  = FileContextUtil.GetFileContextFromFileName(fileName);
                            if (context != FileContext.Include && context != FileContext.Dictionary)
                            {
                                fileIds[rdr.GetInt64(0)] = fileName;
                            }
                        }
                    }
                }

                if (fileIds.Any())
                {
                    Log.Debug("Resetting modified date on {0} file(s).", fileIds.Count);

                    using (var txn = db.BeginTransaction())
                    {
                        using (var cmd = db.CreateCommand("update file_ set modified = '1900-01-01' where rowid = @id"))
                        {
                            foreach (var item in fileIds)
                            {
                                cmd.Parameters.Clear();
                                cmd.Parameters.AddWithValue("@id", item.Key);
                                cmd.ExecuteNonQuery();

                                _currentApp.TrySetFileDate(item.Value, DateTime.MinValue);
                            }
                        }
                        txn.Commit();
                    }
                }
            }

            RestartScanning("Include file changed; scanning dependent files.");
        }
Beispiel #23
0
        public void InsertOrUpdate(FFDatabase db)
        {
            var sb    = new StringBuilder();
            var first = true;

            foreach (var arg in _def.Arguments)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    sb.Append('|');
                }
                sb.Append(arg.ToDbString());
            }
            var argsString = sb.ToString();

            var altFileId = 0L;
            var filePos   = _def.FilePosition;

            if (!string.Equals(filePos.FileName, _file.FileName, StringComparison.OrdinalIgnoreCase))
            {
                altFileId = _app.GetAltFileId(db, filePos.FileName);
            }

            if (_id != 0)
            {
                // TODO: next database version, remove description field
                using (var cmd = db.CreateCommand(@"
					update func set file_id = @file_id, name = @name, sig = @sig, alt_file_id = @alt_file_id, pos = @pos,
					description = null, visible = @visible where rowid = @id
					"                    ))
                {
                    cmd.Parameters.AddWithValue("@id", _id);
                    cmd.Parameters.AddWithValue("@file_id", _file.Id);
                    cmd.Parameters.AddWithValue("@name", _name);
                    cmd.Parameters.AddWithValue("@sig", _sig.ToDbString());
                    cmd.Parameters.AddWithValue("@alt_file_id", altFileId);
                    cmd.Parameters.AddWithValue("@pos", filePos.Position);
                    cmd.Parameters.AddWithValue("@visible", _visible ? 1 : 0);

                    cmd.ExecuteNonQuery();
                }
            }
            else
            {
                using (var cmd = db.CreateCommand(@"
					insert into func (name, app_id, file_id, alt_file_id, pos, sig, visible)
					values (@name, @app_id, @file_id, @alt_file_id, @pos, @sig, @visible);
					select last_insert_rowid();
					"                    ))
                {
                    cmd.Parameters.AddWithValue("@name", _name);
                    cmd.Parameters.AddWithValue("@app_id", _app.Id);
                    cmd.Parameters.AddWithValue("@file_id", _file.Id);
                    cmd.Parameters.AddWithValue("@alt_file_id", altFileId);
                    cmd.Parameters.AddWithValue("@pos", filePos.Position);
                    cmd.Parameters.AddWithValue("@sig", _sig.ToDbString());
                    cmd.Parameters.AddWithValue("@visible", _visible ? 1 : 0);
                    _id = Convert.ToInt64(cmd.ExecuteScalar());
                }
            }
        }